Рекурсия. Дерево жизни. Чистый С. Ubuntu - C (СИ)
Формулировка задачи:
Вывести полный список названий групп живых организмов в дереве жизни с отступами. Количество отступов в каждой записи определяется расстоянием конечного узла с названием от корня дерева. То есть количеством промежуточных узлов от листа к вершине дерева. Названия следует выводить в порядке их чтения из файла. Примерно так:
Дерево жизни надо загрузить из текстового файла:
Текст из файла: (Бактерии,Археи,((Гаптофитовые водоросли,((Бурые водоросли,Диатомовые водоросли),Оомицеты),((Динофитовые водоросли,Споровики),Инфузории)),(Радиолярии,(Фораминиферы,Церкозои)),(Слизевики,((Микроспоридии,((Хитриды,(Зигоспоровые грибы,(Арбускулярные микоризные грибы,(Сумчатые грибы,Коралловидные грибы))))),
(Воротничковые жгутиконосцы,(Губки,((Гребневики,Медузы и родственные виды),(Морские звезды и родственные виды,(Ланцетники,(Асцидии,(Миксины,(Миноги, (Хрящевые рыбы,(Лучеперые рыбы,(Лопастеперые рыбы,(Двоякодышащие,(Амфибии, (Млекопитающие,(Черепахи,(Ящерицы,(Крокодилы,Птицы)))))))))))))),((Морские стрелки,((Мшанки,(Плоские черви,Коловратки)),(Моллюски,(Кольчатые черви, (Немертины,Плеченогие))))),(Круглые черви,(Тихоходки,(Онихофоры,(Пауки,(Двупарноногие многоножки,(Ракообразные,Насекомые))))))))))),((Нитчатые водоросли,(Харофиты,(Печеночные мхи,(Мхи,(Aнтоцеротовые мхи,(Плауновидные, ((Псилотовые,Хвощи,Папоротники),((Саговники,(Гинкго,(Гнетовидные,Хвойные))), (Амборелла,(Кувшинковые,(Бадьян,(Магнолииды,(Однодольные,Эвдикоты) )))))))))))))))))
Решение задачи: «Рекурсия. Дерево жизни. Чистый С. Ubuntu»
textual
Листинг программы
#include <stdio.h>
#include <stdlib.h>
void prtSp(int n,FILE *f)
{
int i;
for (i=0; i<n; i++) fprintf(f," ");
}
int main(int argc, char *argv[])
{
char c;
FILE *fi,*fo;
int p=0,flg=0;
fi=fopen("file.txt","r");
if (fi==NULL)
{
printf("Error by open inp. file!\n");
return 1;
}
fo=fopen("res.txt","w");
if (fo==NULL)
{
printf("Error by open out file!\n");
return 1;
}
while (1)
{
c=getc(fi);
if (c==EOF) break;
if (c==',')
{
if (flg) {fprintf(fo,"\n"); prtSp(p,fo); }
flg=0;
}
else
if (c=='(')
{
if (flg) fprintf(fo,"\n");
if (flg)
prtSp(++p,fo);
else
{prtSp(1,fo); p++;}
flg=0;
}
else
if (c==')')
{
if (flg) { fprintf(fo,"\n"); prtSp(--p,fo); }
flg=0;
}
else
{
if ((c != 10) && (c != 13)) {fprintf(fo,"%c",c); flg=1;}
}
}
fclose(fi);
fclose(fo);
system("PAUSE");
return 0;
}
Объяснение кода листинга программы
Код решает задачу распознавания и разбора синтаксиса языка программирования, используя рекурсию и обход дерева в ширину. Список действий:
- Включение необходимых библиотек: В начале кода подключаются необходимые библиотеки, стандартные в C, для работы с файлами и выводом ошибок.
- Функция для печати пробелов:
Создана вспомогательная функция
prtSp, которая печатает указанное количество пробелов в файл. Это используется для форматирования вывода. - Открытие входного файла:
В функции
mainоткрывается входной файлfile.txtдля чтения с помощью функцииfopen. Если файл не может быть открыт, выводится сообщение об ошибке и программа завершается. - Открытие выходного файла:
Также в функции
mainоткрывается выходной файлres.txtдля записи с помощью функцииfopen. Если файл не может быть открыт, выводится сообщение об ошибке и программа завершается. - Основной цикл программы:
Затем в функции
mainначинается бесконечный цикл, который продолжается до тех пор, пока не встретится символ конца файлаEOF. - Распознавание синтаксиса:
Внутри цикла происходит распознавание синтаксиса. Если встречается запятая
,, то это означает начало нового элемента списка. В этом случае вызывается функцияprtSpдля печати пробелов перед новым элементом. - Управление указателями:
Если встречается скобка
(', то это означает начало нового уровня вложенности. В этом случае вызывается функцияprtSpдля увеличения счетчика уровня отступа. - Управление указателями:
Если встречается скобка
')', то это означает конец текущего уровня вложенности. В этом случае вызывается функцияprtSp` для уменьшения счетчика уровня отступа. - Печать символов:
Если встречается символ, отличный от пробела, запятой, скобки
('и скобки `')', то он печатается в выходной файл. - Закрытие файлов:
После окончания работы с файлами вызываются функции
fcloseдля закрытия входного и выходного файлов. - Завершение программы:
В конце программы вызывается функция
system, которая приостанавливает выполнение программы на некоторое время, ожидая нажатия клавиши. - Возврат значения:
В конце функции
mainвозвращается значение 0, что означает успешное выполнение программы.