Сейчас на форуме: CDK123, zds, tyns777, tihiy_grom, morgot, rmn (+5 невидимых)

 eXeL@B —› Программирование —› Помогите так сказать просветиться немного
Посл.ответ Сообщение

Ранг: 4.1 (гость)
Активность: 0=0
Статус: Участник

Создано: 12 ноября 2008 05:29
· Личное сообщение · #1

Здравствуйте. Собственно пока опыта мало, хочу проконсультироваться по поводу сдледующего листинга. Надеюсь найдутся опытные и объяснят.
Это я случайно обнаружил в интернете. Впринципе я понимаю все основные моменты, но просто хочется убедиться, что допустим этот код в некоторых моментах не полный и не правильный. Язык C++

Сначала код а потом вопросы.
P.S Хотелось бы, чтобы кто-нибудь написал рабочую идеальную версию этой программы
(с его точки зрения конечно), как образец мастерства. Я то сам написал для себя ее, но не уверен, что это оптимально. Даже скажу, что это 100% не оптимально. Мне бы это помогло в чем-то... А ситуация-то в том, что я хочу убедиться, не пропустил ли чего из следующего примера...

********************************************************
Вначале мы определим структуру пары следующим образом:
struct pair {
char* name;
int val;
};

Основная идея состоит в том, что строка имеет ассоциированное с ней целое значение. Легко определить функцию поиска find(), которая поддерживает структуру данных, состоящую из одного pair для каждой отличной от других строки, которая была ей представлена. Для краткости представления используется очень простая (и неэффективная) реализация:
const large = 1024;
static pair vec[large+1};
pair* find(char* p)
/*
поддерживает множество пар "pair":
ищет p, если находит, возвращает его "pair",
иначе возвращает неиспользованную "pair"
*/
{
for (int i=0; vec[i].name; i++)
if (strcmp(p,vec[i].name)==0) return &vec[i];
if (i == large) return &vec[large-1];
return &vec[i];
}

Эту функцию может использовать функция value(), реализующая массив целых, индексированный символьными строками (вместо обычного способа):
int& value(char* p)
{
pair* res = find(p);
if (res->name == 0) { // до сих пор не встречалось:
res->name = new char[strlen(p)+1]; // инициализировать
strcpy(res->name,p);
res->val = 0; // начальное значение 0
}
return res->val;
}

Для данной в качестве параметра строки value() находит целый объект (а не значение соответствующего целого); после чего она возвращает ссылку на него. Ее можно использовать, например, так:
const MAX = 256; // больше самого большого слова
main()
// подсчитывает число вхождений каждого слова во вводе
{
char buf[MAX];
while (cin>>buf) value(buf)++;
for (int i=0; vec[i].name; i++)
cout << vec[i].name << ": " << vec [i].val << "\n";
}

На каждом проходе цикл считывает одно слово из стандартной строки ввода cin в buf (см. Главу 8), а затем обновляет связанный с ней счетчик с помощью find(). И, наконец, печатается полученная таблица различных слов во введенном тексте, каждое с числом его встречаемости. Например, если вводится
aa bb bb aa aa bb aa aa

то программа выдаст:
aa: 5
bb: 3
******************************************************
Мои вопросы:
1). К чему применятся ++ тут while (cin>>buf) value(buf)++;
И зачем он тут вообще нужен.
2). Почему тут if (strcmp(p,vec[i].name)==0) return &vec[i]; сравнивается содержимое строки через ссылку p и индекс массива name. Может быть надо создать переменную хранящую позицию и потом сравнивать
strcmp(p[i],vec[pos].name) под условием, пока не встретится конец строки, и тогда считать сравнение удачным.
3) Когда возвращается return &vec[i]; то что конкретно возвращается, получается ссылка на пустой индекс пустого массива и можно ли вообще создавать Piar vec[] просто так.




Ранг: 170.1 (ветеран), 96thx
Активность: 0.090.01
Статус: Участник

Создано: 12 ноября 2008 08:31
· Личное сообщение · #2

jondos пишет:
неполный и неправильный

"Полнота" зависит от целей. "Правильность" надо вдумчиво проверять - лениво. На первый взгляд - правильно, хотя и неэффективно. MAPs, обычно, реализуют на хэш-таблицах или деревьях.

jondos пишет:
Хотелось бы, чтобы кто-нибудь написал рабочую идеальную версию этой программы

Поискать в google на слово "concordance".

jondos пишет:
1). К чему применяется ++ тут while (cin>>buf) value(buf)++;

К счетчику val вхождений name (инкрементирование счетчика имен - см. код value().)

jondos пишет:
2). Почему тут if (strcmp(p,vec[i].name)==0) return &vec[i]; сравнивается содержимое строки через ссылку p и индекс массива name.

Судя по коду, p - это указатель на char*, vec.name - указатель того же типа, т.е. все корректно.
Единственно, когда я вижу нечто, типа if (==0), то сразу думаю, что этот код переписан с Basic'a. На C пишут так: if (!strcmp(p,vec[i].name))

[i]jondos пишет:
3) Когда возвращается return &vec[i]; то что конкретно возвращается

Указатель на i-ый элемент, типа struct pair*. Поскольку компилятор инициализирует статические переменные, то там {NULL,0}

jondos пишет:
можно ли вообще создавать pair vec[] просто так.

Не понял вопроса. Можно создать статически (конкретного размера), как в данном примере. Можно динамически (через new). Можно на стеке (автоматическая переменная). В любом случае, этот массив должен быть создан до использования соответствующими процедурами и быть внешним по отношению к ним (находиться в охватывающем блоке).


 eXeL@B —› Программирование —› Помогите так сказать просветиться немного
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати