ducdohuunguyen Ответов: 2

Рекурсивная функция никогда не завершается


Мне дали эту задачу, которая должна быть решена с помощью рекурсии.

Слово "лестничная игра" было изобретено Льюисом Кэрроллом в 1877 году. Идея такова
начать с начального слова и менять по одной букве за раз, пока не дойдете до
последнее слово. Каждое слово на этом пути должно быть английским.
Например, начиная с рыбы, вы можете сделать слово лестница к мачте
через следующую лестницу:
РЫБА, ЖЕЛАНИЕ, МЫТЬЕ, ПЮРЕ, МАЧТА
Напишите программу, которая использует рекурсию для поиска слова лестница с заданным началом
Слово и конечное слово, или определяет, существует ли лестница слов.

Что я уже пробовал:

Вот мой код:

#include<fstream>
#include<iostream>
#include<cstdlib>
#include<string>
#include<vector>
using namespace std;

bool possible_bridge(string a, string b)//determine if a bridge can be formed between two strings
{
	if (a.length()!=b.length())
	{
		return false;
	}
	bool difference=false;
	for (int i=0;i<a.length();i++)
	{
		if ((a[i]!=b[i])&&(!difference))
		{
			difference=true;
		}
		else if ((a[i]!=b[i])&&(difference))
		{
			return false;
		}
	}
	return true;
}
bool isRepeat(vector<string>& no_repeat,string word)//determine if there is already an indentical string in the vector
{
	for (int i=0;i<no_repeat.size();i++)
	{
		if (no_repeat[i]==word)
		{
			return true;
		}
	}
	return false;
}
void word_bridge(string last,vector<string>bridge[],bool& found,int size)
{
	ifstream fin;
	int count[size];
	for (int i=0;i<size;i++)
	{
		count[i]=0;
	}
	for (int i=0;i<size;i++)
	{
		string word;
		fin.open("text.dat");
		while (fin>>word)
		{
			if ((possible_bridge(word,bridge[i][bridge[i].size()-1]))&&(!isRepeat(bridge[i],word)))
			{
				count[i]++;
			}
		}
		fin.close();
	}
	int total=0;
	for (int i=0;i<size;i++)
	{
		total+=count[i];
	}
	if (total==0)
	{
		cout<<"no ladder available\n";
		return;
	}
	int n(0),i(0);
	vector<string>temp[total];
	for (int k=0;k<total;k++)
	{
		temp[k]=bridge[i];
		n++;
		if (n==count[i])
		{
			i++;
			n=0;
		}
	}
	n=0;
	i=0;
	string word;
	fin.open("text.dat");
	for (int k=0;k<total;k++)
	{
		do
		{
			fin>>word;
		} while (!((possible_bridge(word,temp[k][temp[k].size()-1]))&&(!isRepeat(temp[k],word))));
		temp[k].push_back(word);
		n++;
		if (n==count[i])
		{
			i++;
			n=0;
			fin.close();
			fin.open("text.dat");
		}
	}
	if (fin.is_open())
	{
		fin.close();
	}
	for (int i=0;i<total;i++)
	{
		if (temp[i][temp[i].size()-1]==last)
		{
			for (int k=0;k<temp[i].size();k++)
			{
				found=true;
				cout<<temp[i][k]<<" ";
			}
			return;
		}
	}
	if (!found)
	{
		word_bridge(last,temp,found,total);
	}
}

int main()
{
	vector<string>bridge[1];
	bridge[0].push_back("ade");
	bool found=false;
	word_bridge("bqe",bridge,found,1);
}



Я протестировал эти функции, и они хорошо работают, за исключением рекурсивной части функции word_bridge. Когда я добавил простую выходную строку cout<<"123" прямо перед рекурсивной частью и запустил программу, программа вывела 123, но не завершила работу и не вывела ничего другого.

jeron1

Вы не задали ни одного вопроса.

2 Ответов

Рейтинг:
20

OriginalGriff

Разработка состоит из четырех частей: проектирование, код, тестирование и отладка.
Вы сделали первые три,и теперь пришло время для самого интересного: отладки.

Почему это не работает? Я не знаю, потому что вы не сказали мне, откуда вы знаете, что это не так - вы не сказали мне, что вы сделали, чтобы проверить это, или какие результаты вы получили. И это важно: они говорят вам, программисту, что не так.

Итак, начните с рассмотрения того, что вы сделали: что вы вошли и что произошло в результате. Любые сообщения об ошибках важны. А выход важен. Как результат соотносится с тем, что вы вводите и чего ожидаете? Когда вы хорошенько подумали об этом, пришло время вытащить отладчик и начать выяснять, почему вы получаете те результаты, которые получаете.
Поставьте точку останова на линии

bridge[0].push_back("ade");
И запустите свое приложение в отладчике.
Когда он достигнет точки останова, он остановится и позволит вам взять верх. Вы можете перешагнуть через линии, войти в функции и посмотреть (или изменить) содержимое переменных. Поэтому посмотрите на каждую строку и определите, что именно должно произойти, когда она будет запущена. Затем выполните линию и посмотрите, что произошло. Это то, что вы ожидали? Если да, то переходите к следующей строке. Если нет, то почему? Что он сделал? Почему он не сделал того, что вы ожидали?

Это навык - и очень ценный в реальной жизни, - но единственный способ развить его-это использовать: Чем больше вы его используете, тем лучше вы получаете! И гораздо проще научиться и развить этот навык на такой маленькой программе, как эта, а не на 100 000-строчном бегемоте, написанном в основном другим разработчиком!

Так что попробуйте и посмотрите, что вы можете узнать - это может быть неприятно, но это действительно забавная часть разработки, когда вы узнаете, в чем проблема!


Рейтинг:
2

Patrice T

Я согласен с OrifinalGriff, вы должны научиться использовать отладчик как можно скорее. Вместо того чтобы гадать, что делает ваш код, пришло время увидеть, как он выполняется, и убедиться, что он делает то, что вы ожидаете.

Отладчик позволяет вам следить за выполнением строка за строкой, проверять переменные, и вы увидите, что есть точка, в которой он перестает делать то, что вы ожидаете.
Отладчик-Википедия, свободная энциклопедия[^]
Освоение отладки в Visual Studio 2010 - руководство для начинающих[^]

Отладчик здесь для того, чтобы показать вам, что делает ваш код, и ваша задача-сравнить его с тем, что он должен делать.
Когда код не делает того, что ожидается, вы близки к ошибке.

У вас тут жучок:

int count[size];
for (int i=0;i<size;i++)>
{
    count[i]=0;
}

Этот код отлично работает, если size известно во время компиляции.
Когда size изменение во время выполнения, вам нужен указатель, и вы должны вручную выделить и освободить память.
ссылка на malloc - C++ [^]
СТД::Танос - cppreference.com[^]
Эта ошибка неприятна, потому что ваш код уничтожает стек, и каждый раз, когда вы вызываете функцию, стек уничтожает вашу переменную.