(Фортран) Поиск одинаковых слов
Существует массив слов. В нем я выбираю слова определенной длины. Мне необходимо узнать количество Одинаковых слов в этом массиве. Подскажите пожалуйста как это можно реализовать?
Хорошо бы если язык...
Gloms, давайте сразу - Вам чего конкретно: алгоритм, код (на Фортране?) или блок-схему?
Существует массив слов. В нем я выбираю слова определенной длины. Мне необходимо узнать количество Одинаковых слов в этом массиве. Подскажите пожалуйста как это можно реализовать?
Я уже писал, что такие http://forum.codenet.ru/showthread.php?t=37700 задачи проще всего решить с помощью конечного автомата.
Ради интереса я написал прогу на основе КА. Ниже код реализирующий КА, он одинаков для всех 5-и задач. С ее помощью программы для тех задач пишутся за пару минут, только в нужное место нужно дописать соотв.код.
#include <stdio.h>
// ********************************************************************* //
// * * //
// * ПЕРЕМЕННЫЕ КОНЕЧНОГО АВТОМАТА * //
// * * //
// ********************************************************************* //
const int MAX_LEN = 200; // Максимальная длина входного текста
enum Lex_type { // Тип текущего символа
ltLETTER, // Буква
ltNUMBER, // Цифра
ltSTOP // Пробел или запятая или точка
}lex_type;
unsigned int state; // Состояние автомата
// 0 - ожидает ввод первого символа слова
// 1 - вводятся символы текущего слова
char cur_char; // текущий символ
bool is_alpha_ex; // true - если при чтении символов текущего слова,
// встретилась хоть одна буква
// false - все символы являются цифрами
unsigned int word_len; // Количество прочтенных символов текущего слова
char in_text[MAX_LEN+1]; // Вводимый текст
unsigned int in_ndx; // Индекс текущего символа
unsigned int number; // Величина числа, если текущее слово является числом
unsigned int first_ndx; // Индекс первого символа текущего слова в in_text
// ********************************************************************* //
// * * //
// * СПЕЦИФИЧЕСКИЕ ПЕРЕМЕННЫЕ ЗАДАЧИ * //
// * * //
// ********************************************************************* //
// ...
// ...
void process()
{
// Инициализация переменных конечного автомата
state = 0; // Ожидание первого символа слова
in_text[MAX_LEN] = '.';
// Инициализация переменных задачи
// ...
// Цикл чтения символов
for(in_ndx = 0; in_ndx <= MAX_LEN; in_ndx++)
{
// Текущий символ
cur_char = in_text[in_ndx];
// Определение типа текущего символа
if(cur_char <= '9' && cur_char >= '0')
lex_type = ltNUMBER;
else if(cur_char == ' ' || cur_char == ',' || cur_char == '.')
lex_type = ltSTOP;
else
lex_type = ltLETTER;
// Обработка
if(state==0) // Ожидается начало слова
{
switch(lex_type)
{
case ltLETTER: // Первый символ слова: буква
word_len = 1; // Текущая длина слова
state = 1; // Смена состояния автомата
first_ndx = in_ndx; // Позиция первого слова в вводимом тексте
is_alpha_ex = true; // Была буква
break;
case ltNUMBER: // Первый символ слова: цифра
word_len = 1; // Текущая длина слова
state = 1; // Смена состояния автомата
is_alpha_ex = false; // Пока еще одни цифры
first_ndx = in_ndx; // Позиция первого слова в вводимом тексте
number = (int)cur_char; // Значение текущего числа
break;
case ltSTOP: // Ограничитель
; // Ничего не меняется
}
}
else // Вводится слово
{
switch(lex_type)
{
case ltLETTER: // Текущий символ является буквой
word_len++; // Текущая длина
is_alpha_ex = true; // Была буква
break;
case ltNUMBER: // Текущий символ является цифрой
word_len++; // Текущая длина
if(is_alpha_ex==false) // Если были одни цифры, вычисляется
number = 10 * number + (int)cur_char; // текущее значение числа
break;
case ltSTOP: // Прочитан ограничитель ==> слово было прочитано
// Обработка слова
// ...
// ...
state = 0; // Смена состояния автомата: ожидание
} // первого символа след.слова
}
if(cur_char == '.') // Если текущий символ является точкой,
break; // тогда прочитан весь текст и выход из цикла.
}
}
int main()
{
// Чтение текста из файла
FILE *fin = fopen("in.txt", "r");
if(!fin)
{
printf("Невозможно открыть файл in.txt для чтения...\n");
return 1;
}
fgets(in_text, MAX_LEN, fin);
fclose(fin);
// Обработка
process();
// Вывод результата
FILE *fout = fopen("out.txt", "r");
fclose(fout);
return 0;
}
#include <stdio.h>
// ********************************************************************* //
// * * //
// * ПЕРЕМЕННЫЕ КОНЕЧНОГО АВТОМАТА * //
// * * //
// ********************************************************************* //
const int MAX_LEN = 200; // Максимальная длина входного текста
enum Lex_type { // Тип текущего символа
ltLETTER, // Буква
ltNUMBER, // Цифра
ltSTOP // Пробел или запятая или точка
}lex_type;
unsigned int state; // Состояние автомата
// 0 - ожидает ввод первого символа слова
// 1 - вводятся символы текущего слова
char cur_char; // текущий символ
bool is_alpha_ex; // true - если при чтении символов текущего слова,
// встретилась хоть одна буква
// false - все символы являются цифрами
unsigned int word_len; // Количество прочтенных символов текущего слова
char in_text[MAX_LEN+1]; // Вводимый текст
unsigned int in_ndx; // Индекс текущего символа
unsigned int number; // Величина числа, если текущее слово является числом
unsigned int first_ndx; // Индекс первого символа текущего слова в in_text
// ********************************************************************* //
// * * //
// * СПЕЦИФИЧЕСКИЕ ПЕРЕМЕННЫЕ ЗАДАЧИ * //
// * * //
// ********************************************************************* //
[color=red]char out_text[MAX_LEN+1]; // Выходная строка
unsigned int out_ndx; // Индекс текущей позиции в out_text
int numbers[20]; // Массив кубов прочитанных чисел
unsigned int numbers_ndx; // Текущее число элементов в numbers
bool is_s_ex; // В текущем слове имеется буква "s"
char buf[16]; // Вспомогательная перменная[/color]
void process()
{
// Инициализация переменных конечного автомата
state = 0; // Ожидание первого символа слова
in_text[strlen(in_text)] = '.';
// Инициализация переменных задачи
[color=red]out_ndx = 0; // Выводимая строка пуста
numbers_ndx = 0; // Количество прочитанных чисел[color]
// Цикл чтения символов
for(in_ndx = 0; in_ndx <= MAX_LEN; in_ndx++)
{
// Текущий символ
cur_char = in_text[in_ndx];
// Определение типа текущего символа
if(cur_char <= '9' && cur_char >= '0')
lex_type = ltNUMBER;
else if(cur_char == ' ' || cur_char == ',' || cur_char == '.')
lex_type = ltSTOP;
else
lex_type = ltLETTER;
// Обработка
if(state==0) // Ожидается начало слова
{
switch(lex_type)
{
case ltLETTER: // Первый символ слова: буква
word_len = 1; // Текущая длина слова
state = 1; // Смена состояния автомата
first_ndx = in_ndx; // Позиция первого слова в вводимом тексте
is_alpha_ex = true; // Была буква
[color=red]if(cur_char == 's')
is_s_ex = true; // Слово содержит букву "s"
else
is_s_ex = false; // Буква "s" пока еще не встречалась[/color]
break;
case ltNUMBER: // Первый символ слова: цифра
word_len = 1; // Текущая длина слова
state = 1; // Смена состояния автомата
is_alpha_ex = false; // Пока еще одни цифры
first_ndx = in_ndx; // Позиция первого слова в вводимом тексте
number = (int)cur_char - 48; // Значение текущего числа
[color=red]is_s_ex = false; // Пока еще буквы s небыло[/color]
break;
case ltSTOP: // Ограничитель
; // Ничего не меняется
}
}
else // Вводится слово
{
switch(lex_type)
{
case ltLETTER: // Текущий символ является буквой
word_len++; // Текущая длина
is_alpha_ex = true; // Была буква
[color=red]if(cur_char == 's')
is_s_ex = true; // Слово содержит букву "s"[color]
break;
case ltNUMBER: // Текущий символ является цифрой
word_len++; // Текущая длина
if(is_alpha_ex==false) // Если были одни цифры, вычисляется
number = 10 * number + (int)cur_char - 48; // текущее значение числа
break;
case ltSTOP: // Прочитан ограничитель ==> слово было прочитано
// Обработка слова
[color=red]if((word_len==5) && // Если длина слова равна 5
!is_s_ex) // и не содержит букву "s"
{
// Копирование слова в строку вывода
strncpy(out_text + out_ndx, in_text + first_ndx, 5);
out_ndx+=5;
out_text[out_ndx++] = ' ';
}
if(!is_alpha_ex) // Если было введено число
{
// Запись куба числа в массив кубов
numbers[numbers_ndx++] = number*number*number;
}[/color]
state = 0; // Смена состояния автомата: ожидание
} // первого символа след.слова
}
if(cur_char == '.') // Если текущий символ является точкой,
break; // тогда прочитан весь текст и выход из цикла.
}
}
int main()
{
// Чтение текста из файла
FILE *fin = fopen("in.txt", "r");
if(!fin)
{
printf("Невозможно открыть файл in.txt для чтения...\n");
return 1;
}
fgets(in_text, MAX_LEN, fin);
fclose(fin);
// Обработка
process();
// Вывод результата
FILE *fout = fopen("out.txt", "w");
// Вывод списка 5 символьных слов
[color=red]if(out_ndx==0)
fputs("Входной текст не содержит слов\nудовлетворяющих заданному условию.", fout);
else
{
out_text[out_ndx] = '\0';
fputs(out_text, fout);
}
// Вывод списка чисел
if(numbers_ndx==0)
fputs("\n\nВходной текст не содержал чисел.", fout);
else
{
fputs("\n\nМассив кубов цифровых слов: \n", fout);
for(unsigned int i = 0; i < numbers_ndx; i++)
{
sprintf(buf, " %d\n", numbers);
fputs(buf, fout);
}
}[/color]
fclose(fout);
return 0;
}
alpha,,,,,23 theta 7,seren , 88 omega
out.txt:
alpha theta omega
Массив кубов цифровых слов:
12167
343
681472
#include <stdio.h>
// ********************************************************************* //
// * * //
// * ПЕРЕМЕННЫЕ КОНЕЧНОГО АВТОМАТА * //
// * * //
// ********************************************************************* //
const int MAX_LEN = 200; // Максимальная длина входного текста
enum Lex_type { // Тип текущего символа
ltLETTER, // Буква
ltNUMBER, // Цифра
ltSTOP // Пробел или запятая или точка
}lex_type;
unsigned int state; // Состояние автомата
// 0 - ожидает ввод первого символа слова
// 1 - вводятся символы текущего слова
char cur_char; // текущий символ
bool is_alpha_ex; // true - если при чтении символов текущего слова,
// встретилась хоть одна буква
// false - все символы являются цифрами
unsigned int word_len; // Количество прочтенных символов текущего слова
char in_text[MAX_LEN+1]; // Вводимый текст
unsigned int in_ndx; // Индекс текущего символа
unsigned int number; // Величина числа, если текущее слово является числом
unsigned int first_ndx; // Индекс первого символа текущего слова в in_text
// ********************************************************************* //
// * * //
// * СПЕЦИФИЧЕСКИЕ ПЕРЕМЕННЫЕ ЗАДАЧИ * //
// * * //
// ********************************************************************* //
[color=red]char words[40][6]; // Массив прочитанных 5-символьных слов
int words_cnt[40]; // Число повторений соответствующего слова
unsigned int words_ndx; // Текущее число элементов в words
int numbers[20]; // Массив деленных на 3 чисел
unsigned int numbers_ndx; // Текущее число элементов в numbers
bool is_dup_ex; // true, если данное слово уже было введено раньше
char buf[16]; // Вспомогательная перменная[/color]
void process()
{
// Инициализация переменных конечного автомата
state = 0; // Ожидание первого символа слова
in_text[strlen(in_text)] = '.';
// Инициализация переменных задачи
[color=red] words_ndx = 0; // Количество прочитанных 5-символьных слов
numbers_ndx = 0; // Количество прочитанных чисел[/color]
// Цикл чтения символов
for(in_ndx = 0; in_ndx <= MAX_LEN; in_ndx++)
{
// Текущий символ
cur_char = in_text[in_ndx];
// Определение типа текущего символа
if(cur_char <= '9' && cur_char >= '0')
lex_type = ltNUMBER;
else if(cur_char == ' ' || cur_char == ',' || cur_char == '.')
lex_type = ltSTOP;
else
lex_type = ltLETTER;
// Обработка
if(state==0) // Ожидается начало слова
{
switch(lex_type)
{
case ltLETTER: // Первый символ слова: буква
word_len = 1; // Текущая длина слова
state = 1; // Смена состояния автомата
first_ndx = in_ndx; // Позиция первого слова в вводимом тексте
is_alpha_ex = true; // Была буква
break;
case ltNUMBER: // Первый символ слова: цифра
word_len = 1; // Текущая длина слова
state = 1; // Смена состояния автомата
is_alpha_ex = false; // Пока еще одни цифры
first_ndx = in_ndx; // Позиция первого слова в вводимом тексте
number = (int)cur_char - 48; // Значение текущего числа
break;
case ltSTOP: // Ограничитель
; // Ничего не меняется
}
}
else // Вводится слово
{
switch(lex_type)
{
case ltLETTER: // Текущий символ является буквой
word_len++; // Текущая длина
is_alpha_ex = true; // Была буква
break;
case ltNUMBER: // Текущий символ является цифрой
word_len++; // Текущая длина
if(is_alpha_ex==false) // Если были одни цифры, вычисляется
number = 10 * number + (int)cur_char - 48; // текущее значение числа
break;
case ltSTOP: // Прочитан ограничитель ==> слово было прочитано
// Обработка слова
[color=red]if(word_len==5) // Если длина слова равно 5
{
// Поиск текущего слова в массиве
// введенных 5-символьных слов
is_dup_ex = false; // Пока еще нет дубликата
for(unsigned int i = 0; i < words_ndx; i++)
{
// Если введенное слово равно, тек.элементу в words
if(strncmp(words, in_text + first_ndx, 5)==0)
{
// Отметка, что слово было найдено
is_dup_ex = true;
// Увеличение числа повторений
words_cnt = words_cnt + 1;
// Выход из цикла, дальше сравнивать нет смысла
break;
}
}
if(is_dup_ex==false) // Если слово не было найдено
{
// Запись слова в массив
strncpy(words[words_ndx], in_text + first_ndx, 5);
words[words_ndx][5] = '\0';
// Установка числа повторений
words_cnt[words_ndx] = 1;
words_ndx++; // Количесво, прочтенных 5-символьных слов
}
}
if(!is_alpha_ex) // Если было введено число
{
// Запись в массив
numbers[numbers_ndx] = number / 3;
numbers_ndx++; // Количество прочтенных чисел
}[/color]
state = 0; // Смена состояния автомата: ожидание
} // первого символа след.слова
}
if(cur_char == '.') // Если текущий символ является точкой,
break; // тогда прочитан весь текст и выход из цикла.
}
}
int main()
{
// Чтение текста из файла
FILE *fin = fopen("in.txt", "r");
if(!fin)
{
printf("Невозможно открыть файл in.txt для чтения...\n");
return 1;
}
fgets(in_text, MAX_LEN, fin);
fclose(fin);
// Обработка
process();
// Вывод результата
FILE *fout = fopen("out.txt", "w");
// Вывод списка 5 символьных слов
[color=red]if(words_ndx==0)
fputs("Входной текст не содержит слов\nудовлетворяющих заданному условию.", fout);
else
{
for(unsigned int i = 0; i < words_ndx; i++)
{
sprintf(buf, " %s %d\n", words, words_cnt);
fputs(buf, fout);
}
}
// Вывод списка чисел
if(numbers_ndx==0)
fputs("\n\nВходной текст не содержал чисел.", fout);
else
{
fputs("\n\nМассив цифровых слов уменьшенных на 3: \n", fout);
for(unsigned int i = 0; i < numbers_ndx; i++)
{
sprintf(buf, " %d\n", numbers);
fputs(buf, fout);
}
}[/color]
fclose(fout);
return 0;
}
alpha 55 betha 11 theta 1 theta alpha .
out.txt:
alpha 2
betha 1
theta 2
Массив цифровых слов уменьшенных на 3:
18
3
0
#include <stdio.h>
// ********************************************************************* //
// * * //
// * ПЕРЕМЕННЫЕ КОНЕЧНОГО АВТОМАТА * //
// * * //
// ********************************************************************* //
const int MAX_LEN = 200; // Максимальная длина входного текста
enum Lex_type { // Тип текущего символа
ltLETTER, // Буква
ltNUMBER, // Цифра
ltSTOP // Пробел или запятая или точка
}lex_type;
unsigned int state; // Состояние автомата
// 0 - ожидает ввод первого символа слова
// 1 - вводятся символы текущего слова
char cur_char; // текущий символ
bool is_alpha_ex; // true - если при чтении символов текущего слова,
// встретилась хоть одна буква
// false - все символы являются цифрами
unsigned int word_len; // Количество прочтенных символов текущего слова
char in_text[MAX_LEN+1]; // Вводимый текст
unsigned int in_ndx; // Индекс текущего символа
unsigned int number; // Величина числа, если текущее слово является числом
unsigned int first_ndx; // Индекс первого символа текущего слова в in_text
// ********************************************************************* //
// * * //
// * СПЕЦИФИЧЕСКИЕ ПЕРЕМЕННЫЕ ЗАДАЧИ * //
// * * //
// ********************************************************************* //
[color=red]char out_text[MAX_LEN+1]; // Выходная строка
unsigned int out_ndx; // Индекс текущей позиции в out_text
int numbers[20]; // Массив прочитанных чисел
unsigned int numbers_ndx; // Текущее число элементов в numbers
char tmp_char, ch_buf; // Вспомогательная переменная
char buf[16]; // Вспомогательная перменная[/color]
void process()
{
// Инициализация переменных конечного автомата
state = 0; // Ожидание первого символа слова
in_text[strlen(in_text)] = '.';
// Инициализация переменных задачи
[color=red]out_ndx = 0; // Выводимая строка пуста
numbers_ndx = 0; // Количество прочитанных чисел[/color]
// Цикл чтения символов
for(in_ndx = 0; in_ndx <= MAX_LEN; in_ndx++)
{
// Текущий символ
cur_char = in_text[in_ndx];
// Определение типа текущего символа
if(cur_char <= '9' && cur_char >= '0')
lex_type = ltNUMBER;
else if(cur_char == ' ' || cur_char == ',' || cur_char == '.')
lex_type = ltSTOP;
else
lex_type = ltLETTER;
// Обработка
if(state==0) // Ожидается начало слова
{
switch(lex_type)
{
case ltLETTER: // Первый символ слова: буква
word_len = 1; // Текущая длина слова
state = 1; // Смена состояния автомата
first_ndx = in_ndx; // Позиция первого слова в вводимом тексте
is_alpha_ex = true; // Была буква
break;
case ltNUMBER: // Первый символ слова: цифра
word_len = 1; // Текущая длина слова
state = 1; // Смена состояния автомата
is_alpha_ex = false; // Пока еще одни цифры
first_ndx = in_ndx; // Позиция первого слова в вводимом тексте
number = (int)cur_char - 48; // Значение текущего числа
break;
case ltSTOP: // Ограничитель
; // Ничего не меняется
}
}
else // Вводится слово
{
switch(lex_type)
{
case ltLETTER: // Текущий символ является буквой
word_len++; // Текущая длина
is_alpha_ex = true; // Была буква
break;
case ltNUMBER: // Текущий символ является цифрой
word_len++; // Текущая длина
if(is_alpha_ex==false) // Если были одни цифры, вычисляется
number = 10 * number + (int)cur_char - 48; // текущее значение числа
break;
case ltSTOP: // Прочитан ограничитель ==> слово было прочитано
// Обработка слова
[color=red]if(!is_alpha_ex) // Если было прочитано число
{
// Запись числа в массив
numbers[numbers_ndx] = number - 23;
numbers_ndx++; // Количество прочитанных чисел
}
if(word_len==5) // Если длина прочитанного слова равна 5
{
// Копирование слова в выходной текст
strncpy(out_text + out_ndx, in_text + first_ndx, 5);
// Группирование одинаковых символов
for(int i = 0; i < 4; i++)
{
tmp_char = out_text[out_ndx+i];
for(int j = i+1; j < 5; j++)
{
if(out_text[out_ndx+j]==tmp_char)
{
ch_buf = out_text[out_ndx+i+1];
out_text[out_ndx+i+1] = tmp_char;
out_text[out_ndx+j] = ch_buf;
break;
}
}
}
// Сдвиг указателя и запись пробела после слова
out_ndx+=5;
out_text[out_ndx++] = ' ';
}[/color]
state = 0; // Смена состояния автомата: ожидание
} // первого символа след.слова
}
if(cur_char == '.') // Если текущий символ является точкой,
break; // тогда прочитан весь текст и выход из цикла.
}
}
int main()
{
// Чтение текста из файла
FILE *fin = fopen("in.txt", "r");
if(!fin)
{
printf("Невозможно открыть файл in.txt для чтения...\n");
return 1;
}
fgets(in_text, MAX_LEN, fin);
fclose(fin);
// Обработка
process();
// Вывод результата
FILE *fout = fopen("out.txt", "w");
// Вывод списка 5 символьных слов
[color=red]if(out_ndx==0)
fputs("Входной текст не содержит слов\nудовлетворяющих заданному условию.", fout);
else
{
out_text[out_ndx] = '\0';
fputs(out_text, fout);
}
// Вывод списка чисел
if(numbers_ndx==0)
fputs("\n\nВходной текст не содержал чисел.", fout);
else
{
fputs("\n\nМассив цифровых слов уменьшенных на 23: \n", fout);
for(unsigned int i = 0; i < numbers_ndx; i++)
{
sprintf(buf, " %d\n", numbers);
fputs(buf, fout);
}
}[/color]
fclose(fout);
return 0;
}
alpha sosna,,,,23 thett yes 87 4
out.txt:
aaphl ssona ttthe
Массив цифровых слов уменьшенных на 23:
0
64
-19
#include <stdio.h>
// ********************************************************************* //
// * * //
// * ПЕРЕМЕННЫЕ КОНЕЧНОГО АВТОМАТА * //
// * * //
// ********************************************************************* //
const int MAX_LEN = 200; // Максимальная длина входного текста
enum Lex_type { // Тип текущего символа
ltLETTER, // Буква
ltNUMBER, // Цифра
ltSTOP // Пробел или запятая или точка
}lex_type;
unsigned int state; // Состояние автомата
// 0 - ожидает ввод первого символа слова
// 1 - вводятся символы текущего слова
char cur_char; // текущий символ
bool is_alpha_ex; // true - если при чтении символов текущего слова,
// встретилась хоть одна буква
// false - все символы являются цифрами
unsigned int word_len; // Количество прочтенных символов текущего слова
char in_text[MAX_LEN+1]; // Вводимый текст
unsigned int in_ndx; // Индекс текущего символа
unsigned int number; // Величина числа, если текущее слово является числом
unsigned int first_ndx; // Индекс первого символа текущего слова в in_text
// ********************************************************************* //
// * * //
// * СПЕЦИФИЧЕСКИЕ ПЕРЕМЕННЫЕ ЗАДАЧИ * //
// * * //
// ********************************************************************* //
[color=red]char out_text[MAX_LEN+1]; // Выходная строка
unsigned int out_ndx; // Индекс текущей позиции в out_text
int numbers[20]; // Массив прочитанных чисел
unsigned int numbers_ndx; // Текущее число элементов в numbers
char tmp_char; // Вспомогательная переменная
char buf[16]; // Вспомогательная перменная[/color]
void process()
{
// Инициализация переменных конечного автомата
state = 0; // Ожидание первого символа слова
in_text[strlen(in_text)] = '.';
// Инициализация переменных задачи
[color=red]out_ndx = 0; // Выводимая строка пуста
numbers_ndx = 0; // Количество прочитанных чисел[color]
// Цикл чтения символов
for(in_ndx = 0; in_ndx <= MAX_LEN; in_ndx++)
{
// Текущий символ
cur_char = in_text[in_ndx];
// Определение типа текущего символа
if(cur_char <= '9' && cur_char >= '0')
lex_type = ltNUMBER;
else if(cur_char == ' ' || cur_char == ',' || cur_char == '.')
lex_type = ltSTOP;
else
lex_type = ltLETTER;
// Обработка
if(state==0) // Ожидается начало слова
{
switch(lex_type)
{
case ltLETTER: // Первый символ слова: буква
word_len = 1; // Текущая длина слова
state = 1; // Смена состояния автомата
first_ndx = in_ndx; // Позиция первого слова в вводимом тексте
is_alpha_ex = true; // Была буква
break;
case ltNUMBER: // Первый символ слова: цифра
word_len = 1; // Текущая длина слова
state = 1; // Смена состояния автомата
is_alpha_ex = false; // Пока еще одни цифры
first_ndx = in_ndx; // Позиция первого слова в вводимом тексте
number = (int)cur_char - 48; // Значение текущего числа
break;
case ltSTOP: // Ограничитель
; // Ничего не меняется
}
}
else // Вводится слово
{
switch(lex_type)
{
case ltLETTER: // Текущий символ является буквой
word_len++; // Текущая длина
is_alpha_ex = true; // Была буква
break;
case ltNUMBER: // Текущий символ является цифрой
word_len++; // Текущая длина
if(is_alpha_ex==false) // Если были одни цифры, вычисляется
number = 10 * number + (int)cur_char - 48; // текущее значение числа
break;
case ltSTOP: // Прочитан ограничитель ==> слово было прочитано
// Обработка слова
[color=red]if(!is_alpha_ex) // Если было введено число
{
// Запись квадрата числа в массив
numbers[numbers_ndx] = number * number;
numbers_ndx++; // Количество прочитанных чисел
}
if(word_len==5) // Если длина числа = 5
{
// Копирование слова в выходной текст
for(int i = 0; i < 5; i++)
{
tmp_char = in_text[first_ndx + i];
if(tmp_char != 'A')
{
out_text[out_ndx] = tmp_char;
out_ndx++;
}
}
// Запись пробела после слова
out_text[out_ndx] = ' ';
out_ndx++;
}[/color]
state = 0; // Смена состояния автомата: ожидание
} // первого символа след.слова
}
if(cur_char == '.') // Если текущий символ является точкой,
break; // тогда прочитан весь текст и выход из цикла.
}
}
int main()
{
// Чтение текста из файла
FILE *fin = fopen("in.txt", "r");
if(!fin)
{
printf("Невозможно открыть файл in.txt для чтения...\n");
return 1;
}
fgets(in_text, MAX_LEN, fin);
fclose(fin);
// Обработка
process();
// Вывод результата
FILE *fout = fopen("out.txt", "w");
// Вывод списка 5 символьных слов
[color=red]if(out_ndx==0)
fputs("Входной текст не содержит слов\nудовлетворяющих заданному условию.", fout);
else
{
out_text[out_ndx] = '\0';
fputs(out_text, fout);
}
// Вывод списка чисел
if(numbers_ndx==0)
fputs("\n\nВходной текст не содержал чисел.", fout);
else
{
fputs("\n\nМассив квадратов цифровых слов: \n", fout);
for(unsigned int i = 0; i < numbers_ndx; i++)
{
sprintf(buf, " %d\n", numbers);
fputs(buf, fout);
}
}[/color]
fclose(fout);
return 0;
}
AlphA sosnA,,,,23 theAt yes 87 4
out.txt:
lph sosn thet
Массив квадратов цифровых слов:
529
7569
16
#include <stdio.h>
// ********************************************************************* //
// * * //
// * ПЕРЕМЕННЫЕ КОНЕЧНОГО АВТОМАТА * //
// * * //
// ********************************************************************* //
const int MAX_LEN = 200; // Максимальная длина входного текста
enum Lex_type { // Тип текущего символа
ltLETTER, // Буква
ltNUMBER, // Цифра
ltSTOP // Пробел или запятая или точка
}lex_type;
unsigned int state; // Состояние автомата
// = 0 - ожидает ввод первого символа слова
// = 1 - вводятся символы текущего слова
char cur_char; // текущий символ
bool is_alpha_ex; // = true, если при чтении символов текущего слова,
// встретилась хоть одна буква
// = false, если все символы слова являются цифрами
unsigned int word_len; // Количество прочтенных символов текущего слова
char in_text[MAX_LEN+1]; // Вводимый текст
unsigned int in_ndx; // Индекс текущего символа
unsigned int number; // Величина числа, если текущее слово является числом
unsigned int first_ndx; // Индекс первого символа текущего слова в in_text
// ********************************************************************* //
// * * //
// * СПЕЦИФИЧЕСКИЕ ПЕРЕМЕННЫЕ ЗАДАЧИ * //
// * * //
// ********************************************************************* //
[color=red]char out_text[MAX_LEN+1]; // Выходная строка
unsigned int out_ndx; // Индекс текущей позиции в out_text
int square; // Квадрат первого числа
bool is_num_ex; // = true, если входе чтения слов, уже было
// прочтено число
char last_char; // Предыдущий прочитанный символ
bool is_seq; // = true, если символы текущего слова
// возростающую последовательность
char buf[16]; // Вспомогательная перменная[/color]
void process()
{
// Инициализация переменных конечного автомата
state = 0; // Ожидание первого символа слова
in_text[strlen(in_text)] = '.';
// Инициализация переменных задачи
[color=red]out_ndx = 0; // Выходная строка пуста
is_num_ex = false; // Пока еще число не было введено[/color]
// Цикл чтения символов
for(in_ndx = 0; in_ndx <= MAX_LEN; in_ndx++)
{
// Текущий символ
cur_char = in_text[in_ndx];
// Определение типа текущего символа
if(cur_char <= '9' && cur_char >= '0')
lex_type = ltNUMBER;
else if(cur_char == ' ' || cur_char == ',' || cur_char == '.')
lex_type = ltSTOP;
else
lex_type = ltLETTER;
// Обработка
if(state==0) // Ожидается начало слова
{
switch(lex_type)
{
case ltLETTER: // Первый символ слова: буква
word_len = 1; // Текущая длина слова
state = 1; // Смена состояния автомата
first_ndx = in_ndx; // Позиция первого слова в вводимом тексте
is_alpha_ex = true; // Была буква
last_char = cur_char; // В след. итерации, это будет пред. символ
[color=red]is_seq = true; // Пока еще все символы больше своих предыдущих[/color]
break;
case ltNUMBER: // Первый символ слова: цифра
word_len = 1; // Текущая длина слова
state = 1; // Смена состояния автомата
is_alpha_ex = false; // Пока еще одни цифры
first_ndx = in_ndx; // Позиция первого слова в вводимом тексте
number = (int)cur_char - 48; // Значение текущего числа
last_char = cur_char; // В след. итерации, это будет пред. символ
[color=red]is_seq = true; // Пока еще все символы больше своих предыдущих[/color]
break;
case ltSTOP: // Ограничитель
; // Ничего не меняется
}
}
else // Вводится слово
{
switch(lex_type)
{
case ltLETTER: // Текущий символ является буквой
word_len++; // Текущая длина
is_alpha_ex = true; // Была буква
[color=red]if(cur_char <= last_char) // Если текущий символ не больше предыдущего,
is_seq = false; // тогда сброс флага[/color]
break;
case ltNUMBER: // Текущий символ является цифрой
word_len++; // Текущая длина
if(is_alpha_ex==false) // Если были одни цифры, вычисляется
number = 10 * number + (int)cur_char - 48; // текущее значение числа
[color=red]if(cur_char <= last_char) // Если текущий символ не больше предыдущего,
is_seq = false; // тогда сброс флага[/color]
break;
case ltSTOP: // Прочитан ограничитель ==> слово было прочитано
// Обработка слова
[color=red]if(!is_alpha_ex) // Если было введено число
{
if(!is_num_ex) // Если это первое число
{
square = number * number; // Вычисление квадрата
is_num_ex = true; // Установка флага
}
}
if(word_len == 5 // Если длина слова равна 5,
&& is_seq) // и символы слова образуют возр.последовательность
{
// Копирование слова в выходной текст
strncpy(out_text + out_ndx, in_text + first_ndx, 5);
// Сдвиг указателя и запись пробела после слова
out_ndx+=5;
out_text[out_ndx] = ' ';
out_ndx++;
}[/color]
state = 0; // Смена состояния автомата: ожидание
} // первого символа след.слова
}
if(cur_char == '.') // Если текущий символ является точкой,
break; // тогда прочитан весь текст и выход из цикла.
}
}
int main()
{
// Чтение текста из файла
FILE *fin = fopen("in.txt", "r");
if(!fin)
{
printf("Невозможно открыть файл in.txt для чтения...\n");
return 1;
}
fgets(in_text, MAX_LEN, fin);
fclose(fin);
// Обработка
process();
// Вывод результата
FILE *fout = fopen("out.txt", "w");
// Вывод списка 5 символьных слов
[color=red]if(out_ndx==0)
fputs("Входной текст не содержит слов\nудовлетворяющих заданному условию.", fout);
else
{
out_text[out_ndx] = '\0';
fputs(out_text, fout);
}
// Вывод числа
if(is_num_ex==0)
fputs("\n\nВходной текст не содержал чисел.", fout);
else
{
sprintf(buf, "\n\nКвадрат первого числа: %d", square);
fputs(buf, fout);
}[/color]
fclose(fout);
return 0;
}
alpha sosna,,,,23 thett yes 87 4 abcde 01234 hhhhh
out.txt:
abcde 01234
Квадрат первого числа: 529
А теперь по-порядку:
1) "отличная" идея использовать каток для разглаживания галстука. Это я про использования конечного автомата для такой примитивной задачи;
2) задача решается за O(n log n), а не за те O(n^2), которые ты предлагаешь;
3) ты когда-нибудь слышал о разбиении программы на логические блоки, функции? Твой код невозможно читать!
4) переменным надо давать ясные имена, а не те невероятные сокращения, перемешенные регистры букв и непонятные "magic numbers";
5) Твои комментарии лишь делают код ещё более нечитабельным;
6) кстати, что это за язык? Си? Не припомню, чтоб в Си были enum-ы и тип bool. Это Си++ ?! Значит, ты совершенно не умеешь пользоваться этим языком.
6) кстати, что это за язык? Си? Не припомню, чтоб в Си были enum-ы и тип bool. Это Си++ ?! Значит, ты совершенно не умеешь пользоваться этим языком.
Навскидку -
1) Зачем тащить хидер <windows.h> для решения примитивной сугубо прикладной консольной задачи??
2) Зачем использовать чар-строки для хранения символом (и вытекающая необходимость использовать всякие strncpy), когда вот уже 12 лет как есть std::string?
3) Зачем использовать sprintf, FILE * , не проще писать на стандартных i/ostream'ах?
4) Зачем выносить ВСЮ прикладную логику в ОДНУ функцию process()?
Ну и собственно, Green тут уже отписался по сути решения..:)
А теперь по-порядку:
1) "отличная" идея использовать каток для разглаживания галстука. Это я про использования конечного автомата для такой примитивной задачи;
2) задача решается за O(n log n), а не за те O(n^2), которые ты предлагаешь;
3) ты когда-нибудь слышал о разбиении программы на логические блоки, функции? Твой код невозможно читать!
4) переменным надо давать ясные имена, а не те невероятные сокращения, перемешенные регистры букв и непонятные "magic numbers";
5) Твои комментарии лишь делают код ещё более нечитабельным;
6) кстати, что это за язык? Си? Не припомню, чтоб в Си были enum-ы и тип bool. Это Си++ ?! Значит, ты совершенно не умеешь пользоваться этим языком.
Что тебя так расстроило? Успокойся. Дышы глубже. :)
Теперь у меня нет времени. Макс. через 2 недели отвечу на этот пост более основательно. Но до тех пор:
Какой каток? В данный момент работаю над программой в которой КА с 43557 состояний и еще пару тысяч состояний добавится. В той КА только два состояния. Ну может кому то он каток...:)
Не исключено, что программы будут переводиться в Fortran, и они писались таким образом, чтоб перевод был как можно более простой, напр. я поэтому не использовал динамические переменные. Не знаю есть ли в Fortran-e ф-ия qsort(вроде вопрос топика как сортировать строки), поэтому я написал тот модуль без сортировки. Может быть 2, 3 макс. 10 слов. На теперешних компах разница в программе с сортировкой и без сортировки будет незаметна.
Из того что ты не можешь прочитать еще не следует, что код вообще нечитаем. Ты хоть в своем коде можешь разобраться?
Не берешь черезчур много на себя?
Несколько раз мне пришлесь менять программу, написанную другим программистом, который был подобно комментирован. Перед тем как разобраться в коде я сперва удалил комментарии. Но в данном случае у тех комментарий 2 цели. 1.проще перевести код в фортран. 2. Их можно записать один к одному в блок-схему.
Если тебя это успокоит, то ты прав, я совершенно не умею пользоваться этим языком :D
1. название темы: (Фортран) Поиск одинаковых слов -> какой нафиг с++? неужели кто-то думает, что найдется чел, который будет переписывать такую тонну кода? или вы думаете автор вопроса знает и с++ и фортран, что без проблем переведет? удивительно! посмотрите его предыдущие посты и вопросы.
2. elan ну привел ты код с КА, зачем постить решения для других задач описанных не в этой теме? надо было там и постить.
3. господа хорош спорить! тема создавалась не для того, чтобы друг другу претензии по коду делать, хотя это можно, если цель не помериться чем-нибудь, а помочь человеку.
4.
[quote=Hrew]Gloms, давайте сразу - Вам чего конкретно: алгоритм, код (на Фортране?) или блок-схему?[/quote]
тут Green предложил решение, но еще раз повторюсь почитайте вопросы автора: надо подробнее, ИМХО, он не поймет, что делать(Gloms без обид).
5. Gloms тебе много чего писали уже и выкладывали в другой твоей теме(т.е. в той что состоит из трех твоих тем), пользуясь некоторыми предложенными отрывками кода, советами из той темы, блок-схемами, наконец, ты вполне можешь решить поставленную задачу и ответить на заданный тобой вопрос самостоятельно.
1. название темы: (Фортран) Поиск одинаковых слов -> какой нафиг с++? неужели кто-то думает, что найдется чел, который будет переписывать такую тонну кода? или вы думаете автор вопроса знает и с++ и фортран, что без проблем переведет? удивительно! посмотрите его предыдущие посты и вопросы.
Не тонна кодов. Нужно перевести шаблон. И к шаблону дописать несколько команд. Счас выделю красным. И даже не нужно переводить. Можно по комментариям понять как работает программа и самому написать код.
я хотел показать как просто решаются такие задачи с использованием КА. Для этого и привел все 5 программ.
Конечно не спорю. С использованием STL программа была бы намного меньше и проще, но ту программу уже точно не переведешь на Fortran.
Я не спорю. У меня 6 постов подряд. Ни в одном ни на кого не наезжал. Но кто-то договорился до того, что я не умею называть переменные (imho называю как хочу) и не умею пользоваться Си++. А чтоб меряться чем либо. Если кто-то на такой простой программе хочет показать какой он супер пупер, то он в жизни действительно сложную программу не видел, не то чтоб написал.
enum есть в С, а bool нет. я помню)
Запускаю цикл i=1,n затем ввожу переменную k=1, далее еще один цикл по j=2,m (чтобы в дальнейшем первый символ уже не сравнивался). Потом ввожу условие a(i)(i:i)=a(j)(j:j).
Такой вопрос, подскажите пожалуйста: необходимо, если буква не совпадет ввести ее в опред. массив, а далее, если мы найдем повторяющийся символ, он должен перейти на позицию того символа, который оказался не верным.
Помогите организовать эту процедуру, буду очень благодарен.