我正在做一个分配,要求我们用值填充AVL树。
代码需要从终端开始一行并执行对树的添加和删除。然后最终按顺序打印AVL树。
来自终端的字符串看起来像这样
A3 A5 A6 D5 D6 print
字符串可以是任意长度的1-100输入长。
我的问题是实现终端读取器功能的最佳方法是什么,该功能可以有效地记录和输入值,甚至初始化输入,删除和打印功能?
我熟悉字符串流和sstream库,但是正在努力找到解决该问题的好方法。
我正在设想的函数的某些伪代码看起来像这样。
void stringReader(string sentence){
string word;
stringstream instring(input);
instring >> word;//word should be a single input ie: "A3" or "D6"
//in the 0th position of the string stream.
if (word == "print"){
printAVL(node* treeroot);
return;
}else{
if(statement to determine if A or D){
//perform deletion or addition;
}
}
input.removeFirstWord()//some magic function I am yet to find that removes the first input
//and allows me to do this recursively.
stringReader(input);
}
int main(){
string input;
getline(cin, input);//the raw input line from terminal ie;"A3 A5 A6 D5 D6 print"
stringReader(input);
}
我不是100%致力于递归方法,也不会对使用sstream库有任何想法或方法心存感激。
编辑-使用while循环并将字符串附加到向量是我正在研究的另一个想法。
感谢您的帮助
PS-任务是判断我们编写AVL树程序的能力,未标记输入的处理。我只想使用一种不错的方法,并有机会进一步发展自己的技能。
您不需要递归函数,也不需要魔术“ removeFirstWord”函数。
如果在std::istringstream
中有数据,并使用>>运算符提取,则数据已经“消失”,您将不再读取它。 stream
的内部机制将推进一些内部指针。 (这是一个非常简化的解释)。
解决方案是,通过一个简单的while循环提取std::istringstream
中的所有单词。提取语句instring >> word
返回对原始std::istringstream
的引用,在本例中为“ instring”。并且bool
的streams
运算符有一个替代值,它指示流的fail
位是否已设置。并且,当流完全“清空”(EOF)时,也将设置此值。
因此,使用命令
while (instring >> word) {
您将读取“ instring”中的所有单词。
然后您可以检查有效命令并执行必要的操作。
您可以在下面的示例中看到它。请注意:我没有实现AVL树。我使用std::set
进行了模拟。您需要自己实现AVL树。
示例(许多可能的解决方案之一:
#include <iostream>
#include <string>
#include <set>
#include <sstream>
// A Pseudo AVL. It is a std::set and a Red Black tree
struct PretendToBeAnAVLtree {
// Data container
std::set<int> data{};
// Add function
void addValue(int value) {
auto result = data.insert(value);
if (!result.second) std::cerr << "\n*** Error Add: Value " << value << " is already in tree\n";
};
// Delete function
void deleteValue(int value) {
auto it = data.find(value);
if (it == data.end())
std::cerr << "\n*** Error Delete: Value " << value << " is not in tree\n";
else
data.erase(it);
}
// Print function
void print() {
for (const int i : data) std::cout << i << " ";
std::cout << "\n\n";
}
};
// Replace PretendToBeAnAVLtree with your implementation of a real AVL tree
using AVL = PretendToBeAnAVLtree;
// Read some string and execute the commands in the input string
void processInputData(const std::string& input, AVL& avl) {
// Some debug output
std::cout << "\nInput data: " << input << "\n";
// Put the input string into an istringstream for easier word extraction
std::istringstream instring(input);
// Now read all words from the istringstream and and consume them
std::string word{};
while (instring >> word) {
// Depending on the command in the word
// Check for print command
if (word == "print") {
avl.print();
} // Check for add command
else if (word[0] == 'A') {
try {
// Convert string starting at position 1 of the word to an integer
int value = std::stoi(word.substr(1));
// Add the value to the tree
avl.addValue(value); }
// In case of conversion error
catch (...) { std::cerr << "\n*** Error: Invalid add command '" << word << "' in input data\n"; }
} // Check for Delete
else if (word[0] == 'D') {
try {
// Convert string starting at position 1 of the word to an integer
int value = std::stoi(word.substr(1));
// Delete the value from the tree
avl.deleteValue(value);
}
// In case of conversion error
catch (...) { std::cerr << "\n*** Error: Invalid delete command '" << word << "' in input data\n"; }
}
else {
// In case of a totaly unknown command
std::cerr << "\n*** Error: Invalid command '" << word << "' in input data\n";
}
}
}
// Driver code
int main() {
// The AVL
AVL avl;
// Some test commands
processInputData("A3 A5 A6 D5 D6 print", avl);
processInputData("A1 A2 A4 A5 print A6 A7 A8 A9 print", avl);
processInputData("A3 A100 print", avl);
processInputData("D3 D4 D555 print", avl);
processInputData("A200 X999 A300 print", avl);
return 0;
}