Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
0 / 0 / 0
Регистрация: 13.04.2010
Сообщений: 4

"Словесная игра"

13.04.2010, 16:29. Показов 1689. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Собственно суть задачи :
В нашем варианте игры каждая буква имеет цену, и вы должны составить из букв одно и более слов, дающих максимальную суммарную стоимость. Даны цены букв , список русских слов и набор букв. Найдите в словаре или пары слов с наибольшей суммарной стоимостью , которые можно составить из заданного набора букв.
Цены букв во вложении.
Входные данные:
С клавиатуры вводим одну строку с маленькими русскими буквами(допустимые буквы- от "а" до "я").Строка содержит от трех до семи букв вкючительно , в произвольном порядке.
Файл словарь "words.txt" содержит не более 30 000(100 слов за глаза хватит). В конце этого файла находится строка с единственным символом "."(точка). Каждая из остальных строк содержит слово длиной от трех до семи маленьких латинских букв,включительно . Слова в файле упоряжочены по алфавиту.
Выходные данные:
В первую строку выходного файла output.txt ваша программа должна написать наибольшую возможную суммарную стоимость , а в следующих строках - перечислить все допустимые слова и, или пары слов из словаря words.txt с такой стоимостью. Каждое слово или пару выводите на отдельную строку.

P.S Наверное перестановки это главное в этой программе . Думаю там рекурсия.(Лаба так называется)
Миниатюры
"Словесная игра"  
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
13.04.2010, 16:29
Ответы с готовыми решениями:

Игра Кости, игра с компьютером
Всем привет! Делаю консольную игру Кости. Условия такие: 1) Перед игрой все игроки бросают кость, первым начинает тот, у кого выпало...

Игра слов, игра Scrabble
Задание: Создать программу для решения задачи построения слова из некоторого множества букв (игра Scrabble) используя алгоритмы поиска в...

Как сделать так, чтобы при нажатии на кнопку "Новая игра" игра начиналась заново?
Как сделать так, чтобы при нажатии на кнопку "Новая игра" игра начиналась заново? unit1.cpp void __fastcall TForm1::N1Click(TObject...

11
0 / 0 / 0
Регистрация: 13.04.2010
Сообщений: 4
15.04.2010, 19:47  [ТС]
Вот то что получилось у меня, проблема в том что функция перестановок у меня не правильная.
Нужно генерировать перестановки не только из того количества букв которые дали ,но и с меньшим кол-вом.
Поясню
пользователь ввел буквы а б в г д
программа будет генерировать перестановки со всеми буквами сразу.
а нужно чтобы генерерировало с
а б в г д
а б в г
а б в
в г д
и так далее...
как это реализовать не могу понять .
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <conio.h>
#include <stdio.h>
#include <iostream>
 
using namespace std;
 
 FILE *in,*word,*slova;
 int n1;
 char *a = new char[n1];
//---------------------------------------------------------------------------------------------------------------   
int scoreg(char *symbs)//функция которой мы передаем слово оно выдает кол-во очков
{
    int score=0,o=0;
    char y;
    y=symbs[0];
    while (y!=NULL)
    {   y=symbs[o];
        switch(y)
                {
                    case 'а':score=score+1;break;
                    case 'б':score=score+4;break;
                    case 'в':score=score+3;break;
                    case 'г':score=score+4;break;
                    case 'д':score=score+3;break;
                    case 'е':score=score+1;break;
                    case 'ж':score=score+5;break;
                    case 'з':score=score+5;break;
                    case 'и':score=score+1;break;
                    case 'й':score=score+5;break;
                    case 'к':score=score+1;break;
                    case 'л':score=score+1;break;
                    case 'м':score=score+1;break;
                    case 'н':score=score+1;break;
                    case 'о':score=score+2;break;
                    case 'п':score=score+2;break;
                    case 'р':score=score+2;break;
                    case 'с':score=score+2;break;
                    case 'т':score=score+2;break;
                    case 'у':score=score+5;break;
                    case 'ф':score=score+7;break;
                    case 'х':score=score+7;break;
                    case 'ц':score=score+8;break;
                    case 'ч':score=score+8;break;
                    case 'ш':score=score+9;break;
                    case 'щ':score=score+9;break;
                    case 'ъ':score=score+9;break;
                    case 'ы':score=score+9;break;
                    case 'ь':score=score+9;break;
                    case 'э':score=score+6;break;
                    case 'ю':score=score+6;break;
                    case 'я':score=score+5;break;
            }
                y=symbs[o];
                o++;
    }
    return score;
}
//----------------------------------------------------------------------------------------------------------------------------
void per(char *s,int n)//рекурсивная функция перестановок
 {
     int d;
     int i,j;
     if(n>1)
     {
        per(s,n-1);
        for(i=n-1;i>=1;i--)
        {   
            d=s[n-1];
            s[n-1]=s[i-1];
            s[i-1]=d;
            per(s,n-1);
            d=s[n-1];
            s[n-1]=s[i-1];
            s[i-1]=d;
        }
     
     }
     else
     {
         for(j=1;j<=n1;j++)
         {if (s[j-1]<=-81)fprintf(in,"%c",320+s[j-1]);
          if (s[j-1]>-81)fprintf(in,"%c",272+s[j-1]);
         }
         fprintf(in,"\n");
     }
 }
//----------------------------------------------------------------------------
int main(void)// Главная функция;
{
setlocale (LC_ALL,"RUS");
cout<<"Введите кол-во букв: ";
cin>>n1;
cout<<"Введите буквы: ";
for(int i=0;i<n1;i++)
cin>>a[i];  
in=fopen("combinations.txt","w");
per(a,n1);
fclose(in);
//----------------------------------------------------------------------------------
in=fopen("combinations.txt","r");
slova=fopen("slova.txt","w");
//-------------------------------------------------------------------------------
char *str,*str1,*str2;
int g;
str=new char [50];
str1=new char [50];
str2=new char [50];
//-----------------------------------------------------------------------------
while(!feof(in))//проверяем все перестановки на "слово" и пишем в файл slova.txt
{
   fscanf(in,"%s",str1);
   word=fopen("word.txt","r");
   fscanf(word,"%s",str2);
   while(!feof(word))
    {
        if(strcmp(str1,str2)==0) {fprintf(slova,"%s",str1);fprintf(slova,"\n");}
         fscanf(word,"%s",str2);
     
   }
fclose(word); 
}
fclose(slova);
slova=fopen("slova.txt","r");
//----------------------------------------------------------------------------
while (!feof(slova))//считаем стоимость слов.
{fscanf(slova,"%s",str);
cout<<str<<"\n";
g=scoreg(str);
cout<<g<<"\n";
}
//-----------------------------------------------------------------------------
//закрытие файлов
fclose(slova);
fclose(in);
}
0
Эксперт С++
 Аватар для valeriikozlov
4728 / 2549 / 757
Регистрация: 18.08.2009
Сообщений: 4,568
18.04.2010, 19:37
Цитата Сообщение от R@nDoM Посмотреть сообщение
Нужно генерировать перестановки не только из того количества букв которые дали ,но и с меньшим кол-вом.
А может все проще сделать. Берем первое слово в словаре. Если в этом слове есть буквы которые мы не вводили, то переходим сразу к следующему слову в словаре. Если все буквы данного слова совпали с введенными и их кол-во равно введенным, то вычисляем стоимость и сравниваем ее с текущей (изначально текущая стоимость, как Вы догадались равна 0). Если остались еще свободные буквы (из введенных), то продолжаем поиск второго слова состоящего только из оставшихся букв (продолжаем поиск не с начала словаря а со следующего слова до конца словаря).
По-моему так намного проще.
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
18.04.2010, 21:08
Пара вопросов:
1. Мы вводим от 3 до 7 букв, но обязательно ли слово из словаря тоже должно быть длиной от 3 до 7 букв соответственно? Т.е. могут ли введённые буквы в результирующем слове (паре слов) повторяться?
2. Все слова в словаре идут поодиночке? Отдельных пар в словаре нету, т.е. нашу пару мы можем составить только из пары записей в словаре?
0
0 / 0 / 0
Регистрация: 13.04.2010
Сообщений: 4
19.04.2010, 03:36  [ТС]
Цитата Сообщение от silent_1991 Посмотреть сообщение
1. Мы вводим от 3 до 7 букв, но обязательно ли слово из словаря тоже должно быть длиной от 3 до 7 букв соответственно? Т.е. могут ли введённые буквы в результирующем слове (паре слов) повторяться?
Буквы не повторяются
Цитата Сообщение от silent_1991 Посмотреть сообщение
Все слова в словаре идут поодиночке? Отдельных пар в словаре нету, т.е. нашу пару мы можем составить только из пары записей в словаре?
Да
Цитата Сообщение от valeriikozlov Посмотреть сообщение
А может все проще сделать. Берем первое слово в словаре. Если в этом слове есть буквы которые мы не вводили, то переходим сразу к следующему слову в словаре. Если все буквы данного слова совпали с введенными и их кол-во равно введенным, то вычисляем стоимость и сравниваем ее с текущей (изначально текущая стоимость, как Вы догадались равна 0). Если остались еще свободные буквы (из введенных), то продолжаем поиск второго слова состоящего только из оставшихся букв (продолжаем поиск не с начала словаря а со следующего слова до конца словаря).
По-моему так намного проще.
Может быть и проще , только где тут рекурсия?
0
Эксперт С++
 Аватар для valeriikozlov
4728 / 2549 / 757
Регистрация: 18.08.2009
Сообщений: 4,568
19.04.2010, 05:54
Цитата Сообщение от R@nDoM Посмотреть сообщение
Может быть и проще , только где тут рекурсия?
Ну например рекурсию можно использовать так (я в качестве примера накидаю в общих чертах рек. функцию поиска слова (двух слов) с максимальной стоимостью):
C++
1
2
3
4
5
int rec_func(int temp_i, int col_w, int temp_sum, char *mas)// здесь в качестве параметров передаются: temp_i - текущий индекс слова в словаре, col_w - количество уже задействованных слов (их может не более 2-х), temp_sum - текущая сумма слова (двух слов), *mas - массив свободных букв (в принципе вместо него можно использовать и массив int-вских значений, для указания индексов свободных букв, которые ввели).
Сама функция должна выполнять следующее:
- проверку на то что набранных слов не более 2-х и проверку что не достигли конца словаря;
- проверку очередного слова из словаря для набора введенных символов;
- если очередное слово подходит и буквы еще остались, то вызываем снова нашу rec_func().
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
19.04.2010, 11:59
Я бы дела так. Ищем все комбинации введённых букв (не обязательно всего набора) (можно буквы пронумеровать индексами от 1 до 3 (4, 5, 6, 7, в зависимости от ввода) и искать комбинации цифр 123, либо 1234, 12345, 123456, 1234567, а потом для каждого найденного набора вместо цифры подставлять нужную букву), далее для каждого найденного набора букв искать все слова в словаре, совпадающие с найденным наборами. Заносить эти слова в, например, массив строк. Далее мы просто считаем вЕсы всех найденных слов или их пар (пару составляем так: берём первое слово, далее подставляем к нему второе, третье, ... , n-е, затем берём второе слово, к нему подставляем третье, ..., n-е и т.д, но это и так понятно))) ), находим максимальный, а затем снова просматриваем массив строк, составляя слова (или пары) с найденным весом. Выводим переменную max (максимальный вес) и отредактированный массив строк, содержащий только слова (или пары) с таким весом.
Скорее всего рекурсия будет в функции, ищущей наборы букв.

Добавлено через 50 минут
Так, вся фишка сейчас в том, чтобы написать функцию, ищущую все эти возможные перестановки... Думаю, нужно написать сначала код, ищущий перестановку N чисел, и затем для каждой найденной перестановки рекурсивно применять его для N-1 чисел...

Добавлено через 32 минуты
Так, чтобы перебрать все возможные варианты для N цифр, мы просто берём последнюю цифру числа и "тянем" её через всё число, пока она не займёт первую позицию. Затем в получившемся числе берём последнюю цифру и опять "тянем" её вдоль числа до первой позиции и т.д. Продолжаем, пока последнее число не совпадёт с исходным. Пример для числа 123 (для нашей задачи: например, пользователь ввёл "адф". Нумеруем а = 1, д = 2, ф = 3, ищем комбинацию для 123, подставляем вместо цифр соответствующие буквы и ищем получившееся слово в словаре)
Пример: пользователь ввёл отк. Нумеруем: о = 1, т = 2, к = 3. Ищем комбинации
123 132 312
321 231
213 123 (совпало с начальным -> отбрасываем последний результат).
Получили ряд
123 132 312 321 231 213 он соответствует словам
отк окт кот кто тко ток
Скорее всего найденные в словаре слова будут: кот, кто, ток

Осталось подумать, пренебречь ли ресурсами и тупо ко всем найденным перестановкам рекурсивно применять алогритм для меньшего числа цифр (тогда будут повторяться некоторые наборы, соответственно будет происходить повторная процедура поиска), или же пренебречь памятью и хранить все найденные перестановки в массиве строк, исключая повторения, а уже после нахождения ВСЕХ возможных перестановок включать процедуру поиска...

Добавлено через 18 секунд
И я склоняюсь ко второму варианту.
0
Эксперт С++
 Аватар для valeriikozlov
4728 / 2549 / 757
Регистрация: 18.08.2009
Сообщений: 4,568
19.04.2010, 19:19
Цитата Сообщение от silent_1991 Посмотреть сообщение
Так, чтобы перебрать все возможные варианты для N цифр, мы просто берём последнюю цифру числа и "тянем" её через всё число, пока она не займёт первую позицию.
Для примера в котором всего три буквы этот вариант пройдет.
silent_1991, попробуйте так: начальное число - 1234. Комбинацию 1432 Вы таким способом не получите...
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
20.04.2010, 16:28
valeriikozlov,
Хи, и правда... А я вроде всё проверил, обрадовался))) Есть какой-то другой способ? Алгоритмический?

Добавлено через 19 минут
А если так: делаем инкремент для чисел с 1 по N, а затем удаляем из полученного набора все вхождения чисел, в которых на каком-либо разряде стоит цифра больше N (или же 0)? Единственная загвоздка: для 7 введённых букв придётся хранить 7654321 чисел...

Добавлено через 4 минуты
Тогда можно делать, как я предлагал раньше, ищем следующую комбинацию, проверяем её на правильность (ищем разряды, большие N или нулевые), и сразу выполняем процедуру поиска. Ну или можно искать комбинацию, проверять её на правильность, а уже потом записывать в наш список комбинаций... Правда так всё равно будет куча операций прибавления единицы, но зато просто и зходу найдутся все возможные варианты перестановок не только с данным количеством разрядов, но и с меньшим... И никакой рекурсии)))

Добавлено через 14 минут
Вот, вроде придумал алгоритм...
Берём выборку для одной цифры. Скажем мы ввели три буквы. получили число 123. Возьмём выборку:

1
2
3

Далее для каждой найденной выборки добавляем один младший разряд и в него записываем каждую недостающую цифру. Взяли 1. Недостающие цифры - 2 и 3. получили

12
13

Так же поступаем с остальными. Недостающий цифры для 2 - 1 и 3, для 3 - 1 и 2. Распишем:

21
23

31
32

Далее в каждой найденной выборке предыдущего шага (т.е. из двух, в данном случае, цифр) добавляем ещё разряд и в него записываем недостающие цифры для каждой пары (например для 23 недостающая цифра - 1, для 31 - 2 и т.д.). Получаем:

123
132
213
231
312
321

Всё, перебрали все варианты - выходим (как критерий можно использовать то, что изначальное расположение цифр 123, а конечно всегда будет перевёрнутым - 321. Только что ради эксперимента расписал для четырёх цифр - получилось 64 комбинации). Думаю, это надо рекурсивно реализовать...

Добавлено через 42 минуты
Кстати, для 7 цифр число размещений будет равно 13699... Нехило, а?)))

Добавлено через 16 часов 32 минуты
Так, научился считать все перестановки N цифр... Теперь надо придумать, как считать перестановки для N-1 цифр... Есть идея у всех перестановок предыдущего ((K-1)-го) шага отсекать последний разряд и для каждого получившегося набора рекурсивно запускать функцию перестановки. Для каждой найденной перестановки проверять, нет ли уже такой перестановки в нашем массиве перестановок, если нет - записывать туда найденный набор, если есть - искать следующую перестановку...
Правда поиск уже для 5 разрядов визуально заметен, а для 7 занимает (на глаз) 2,5 - 3 секунды...
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
23.04.2010, 21:44
Жаль, что тема сдохла... А у меня появился код формирования всех сочетаний без повторенийдля чисел от 1 до N...

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <stdio.h>
#include <string.h>
 
#define maxn 8
#define raz 32
#define beg 1
 
unsigned int set[maxn], razr[maxn];
 
int add_set(unsigned int s[], int n)
{
    if (n / raz < maxn)
    {
        s[n / raz] |= 0x01 << (n % raz);
    }
    else
    {
        return -1;
    }
    
    return 0;
}
 
int del_set(unsigned int s[], int n)
{
    if (n / raz < maxn)
    {
        s[n / raz] &= ~(0x01 << (n % raz));
    }
    else
    {
        return -1;
    }
    
    return 0;
}
 
int pr_set(unsigned int s[], int n)
{
    if (n / raz < maxn)
    {
        if ((s[n / raz] >> (n % raz)) & 0x01)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
    else
    {
        return -1;
    }
}
 
void rast(int n, int yr, int n_yr)
{
    int i;
    
    if (n_yr == yr)
    {
        for (i = 0; i < n_yr; i++)
        {
            printf("%d", razr[i]);
        }
        
        printf("\n");
        del_set(set, razr[yr - 1]);
        
        return;
    }
    
    for (i = razr[yr] + 1; i < (beg + n); i++)
    {
        if (!pr_set(set, i))
        {
            del_set(set, razr[yr]);
            add_set(set, i);
            razr[yr] = i;
            rast(n, yr + 1, n_yr);
        }
    }
    
    del_set(set, razr[yr]);
    razr[yr] = beg - 1;
}
 
int main()
{
    int n;
    int i;
    
    printf("Введите количество разрядов: ");
    scanf("%d", &n);
    
    for (i = 0; i < maxn; i++)
    {
        razr[i] = beg - 1;
    }
    
    for (i = 1; i <= n; i++)
    {
        rast(n,0,i);
    }
    
    getch();
    return 0;
}
0
0 / 0 / 0
Регистрация: 13.04.2010
Сообщений: 4
24.04.2010, 04:48  [ТС]
а нужны буквы.
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
24.04.2010, 06:11
И? Нумеруем буквы...
abc
123
Делаем все перестановки
1
2
3
12
13
23
21
31
32
123
132
213
231
312
321

Получаем

a
b
c
ab
ac
bc
ba
ca
cb
abc
acb
bac
bca
cab
cba

И теперь с этим набором работаем.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
24.04.2010, 06:11
Помогаю со студенческими работами здесь

Предикаты. Словесная формулировка
Пусть P(x,y,z) это xy=z, E(x,y)это x=y, G(x,y) это x&gt;y. Надо найти логическую запись предложения &quot;x&lt;z есть необходимое условие...

Словесная запись числа
Вводим любое число от -999999 до 999999 Программа выводит это же число, но буковами Без циклов, без функций. Ура, можно использовать...

Словесная запись числового выражения.
Помогите пожалуйста!! Нужно решить задачу следующего вида: Словесная запись числового выражения. Разработать программу, которая по...

Нужна словесная запись этой задачи
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace...

Словесная форма представления логических элементов
Здравствуйте. Помогите, пожалуйста, составить словесное описание логических функций &quot;Штрих Шеффера&quot; и импликации. Как пример...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru