终端输入的字符串流可变长度,什么是最好的实现方式
String stream variable length of inputs from terminal, what is the best way to implement
我正在做一项作业,要求我们用值填充 AVL 树。
代码需要从终端获取一行并对树执行添加和删除操作。然后最后按顺序打印AVL树。
来自终端的字符串看起来像这样
A3 A5 A6 D5 D6 print
字符串可以是 1 - 100 输入长度的任意长度。
我的问题是实现终端 reader 功能的最佳方式是什么,该功能将有效地记录和输入值,甚至初始化输入、删除和打印功能?
我熟悉字符串流和 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
中有数据,你用>>操作符提取它们,那么数据已经是"gone",你不会再读了。 stream
的内部机制会推进一些内部指针。 (这是一个非常简化的解释)。
解决方案是,用一个简单的 while 循环提取 std::istringstream
中的所有单词。提取语句 instring >> word
returns 对原始 std::istringstream
的引用,在本例中为 "instring"。并且 streams
的 bool
运算符被覆盖,它指示是否设置了流的 fail
位。而且,这也被设置,当流 "emptied" 完全 (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;
}
我正在做一项作业,要求我们用值填充 AVL 树。
代码需要从终端获取一行并对树执行添加和删除操作。然后最后按顺序打印AVL树。
来自终端的字符串看起来像这样
A3 A5 A6 D5 D6 print
字符串可以是 1 - 100 输入长度的任意长度。
我的问题是实现终端 reader 功能的最佳方式是什么,该功能将有效地记录和输入值,甚至初始化输入、删除和打印功能?
我熟悉字符串流和 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
中有数据,你用>>操作符提取它们,那么数据已经是"gone",你不会再读了。 stream
的内部机制会推进一些内部指针。 (这是一个非常简化的解释)。
解决方案是,用一个简单的 while 循环提取 std::istringstream
中的所有单词。提取语句 instring >> word
returns 对原始 std::istringstream
的引用,在本例中为 "instring"。并且 streams
的 bool
运算符被覆盖,它指示是否设置了流的 fail
位。而且,这也被设置,当流 "emptied" 完全 (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;
}