我的输入是这样的(输入的前两行):
{4 <1,-1,-1> <1,1,-1> <-1,1,-1> <-1,-1,-1>} //first line
{4 <1,3,-1> <1,1,-1> <1,1,0.5> <1,3,0.5>}
{4 <1,3,-1> <-1,3,-1> <-1,1,-1> <1,1,-1>}
{4 <-1,3,-1> <-1,3,0.5> <-1,1,0.5> <-1,1,-1>}
{4 <1,3,0.5> <1,1,0.5> <0.75,1,1> <0.75,3,1>}
{4 <-0.75,3,1> <-0.75,1,1> <-1,1,0.5> <-1,3,0.5>}
{4 <-0.75,3,1> <0.75,3,1> <0.75,1,1> <-0.75,1,1>}
{4 <1,-1,0.5> <1,-0.75,1> <3,-0.75,1> <3,-1,0.5>}
{4 <1,-1,0.5> <3,-1,0.5> <3,-1,-1> <1,-1,-1>}
{4 <1,-1,-1> <3,-1,-1> <3,1,-1> <1,1,-1>} //tenth line
我有这样的代码,我希望按顺序读取每个括号,即1,-1,-1,然后在输入文件中搜索它们以细化相似的括号并显示出来,但是没有:>
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
using namespace std;
using vecstr = vector<string>;
vecstr splitOut(const string &line) {
size_t pos = 0;
vecstr result;
while ( (pos=line.find('<',pos)) != string::npos ) {
size_t endpos = line.find('>',pos);
if ( endpos != string::npos ) {
string token = line.substr(pos+1,endpos-pos-1);
result.push_back(token);
} else {
}
pos = endpos;
}
return result;
}
int main ( ) {
ifstream iss("a.txt");
string line;
int offset;
unsigned int curLine = 0;
while (getline(iss,line)){
string test = line;
vecstr result = splitOut(test);
for ( auto s : result ) {
while(getline(iss, line)) {
curLine++;
if ((offset = line.find(s, 0)) != string::npos) {
cout << "found: " << s << " line: " << curLine << endl;
}
}
}
}
}
代码显示的所有输出(我的意思是,它不考虑其他括号以及第一行显示的行不正确,它们应为9和10):
found: 1,-1,-1 line: 8
found: 1,-1,-1 line: 9
如何更改程序以向我显示这样的输出(例如,对于第一个括号,即1,-1,-1):
found: 1,-1,-1 line: 9
found: 1,-1,-1 line: 10
答案 0 :(得分:0)
如果我正确理解了您的问题,则希望查找多次出现的三元组的行号。
我建议保留一个unordered_map<string, int>
,将每个三元组映射到您看到的第一行。
然后您可以按以下方式构建程序:
通过使用比int
更复杂的值类型,可以轻松更改程序的行为。例如,通过保留pair<int, bool>
,您可以只记录第一个重复发生然后停止。或者您用pair<int, int>
来记录第一次出现的次数和之后发生的重复次数。
答案 1 :(得分:0)
我不得不承认,我不太了解代码的逻辑或如何获得输出。无论如何,我很确定这是不正确的...
这里:
while (getline(iss,line)){
string test = line;
vecstr result = splitOut(test);
for ( auto s : result ) {
while(getline(iss, line)) {
curLine++;
if ((offset = line.find(s, 0)) != string::npos) {
cout << "found: " << s << " line: " << curLine << endl;
}
}
}
}
到curLine++
时,您已经通过getline(iss, line)
读了2行,因此您的行号必须关闭。另外,一旦您通过内部getline
读取了所有行,外部循环就不再有任何内容可读取。
与其尝试在文件中来回跳转,不如读取一次,然后处理内存中的数据。我建议一种数据结构,该数据结构可容纳一行中的所有数据。类似于:
struct entry {
size_t line_number;
std::array< std::array< int,3> 3> triples;
};
读取它们,将它们存储在向量中,然后计算所需的结果。
答案 2 :(得分:0)
如果打算在阅读时对行进行计数,则需要对所阅读的每行 进行计数:
while (getline(iss,line)) {
++curLine; // <----------- count here
string test = line;
vecstr result = splitOut(test);
for ( auto s : result ) {
while(getline(iss, line)) {
++curLine; // <----------- as well as here
答案 3 :(得分:0)
使用地图数据结构并将三元组的行号记录在矢量中,该问题很容易实现。
假设输入是您给定的-{number <triplets>…}
,其中triplets
是三胞胎的行,其中每个三元组之间的数字之间没有空格。
给出所有这些,这是一个带有注释的小示例:
#include <unordered_map>
#include <string>
#include <vector>
#include <sstream>
#include <iostream>
std::string test =
"{4 <1,-1,-1> <1,1,-1> <-1,1,-1> <-1,-1,-1>}\n"
"{4 <1,3,-1> <1,1,-1> <1,1,0.5> <1,3,0.5>}\n"
"{4 <1,3,-1> <-1,3,-1> <-1,1,-1> <1,1,-1>}\n"
"{4 <-1,3,-1> <-1,3,0.5> <-1,1,0.5> <-1,1,-1>}\n"
"{4 <1,3,0.5> <1,1,0.5> <0.75,1,1> <0.75,3,1>}\n"
"{4 <-0.75,3,1> <-0.75,1,1> <-1,1,0.5> <-1,3,0.5>}\n"
"{4 <-0.75,3,1> <0.75,3,1> <0.75,1,1> <-0.75,1,1>}\n"
"{4 <1,-1,0.5> <1,-0.75,1> <3,-0.75,1> <3,-1,0.5>}\n"
"{4 <1,-1,0.5> <3,-1,0.5> <3,-1,-1> <1,-1,-1>}\n"
"{4 <1,-1,-1> <3,-1,-1> <3,1,-1> <1,1,-1>}";
int main()
{
// map of "<x,y,z>" strings to a vector of line numbers where <x,y,z> is found
std::unordered_map<std::string, std::vector<int>> triplet_map;
std::istringstream strm(test);
std::string line;
std::string triplet;
int line_number = 1;
while (getline(strm, line))
{
// remove the ending }
line.pop_back();
// find the first <
auto first_pos = line.find_first_of('<');
// start reading from there
std::istringstream linestrm(line.c_str() + first_pos);
while (linestrm >> triplet)
{
// insert the triplet in the map if not already there
// insert() returns an iterator to the inserted item, or the existing
// item in the map if not newly inserted.
auto pr = triplet_map.insert({ triplet, std::vector<int>() });
// record the line number in the vector
pr.first->second.push_back(line_number);
}
++line_number; // update the line number
}
// Output statistics
for (auto& m : triplet_map)
{
// Only output if vector size is > 1
if (m.second.size() > 1)
{
for (auto& v : m.second)
std::cout << "found: " << m.first << " line: " << v << "\n";
std::cout << "\n";
}
}
}
输出看起来类似于:
found: <3,-1,-1> line: 9
found: <3,-1,-1> line: 10
found: <3,-1,0.5> line: 8
found: <3,-1,0.5> line: 9
found: <-0.75,1,1> line: 6
found: <-0.75,1,1> line: 7
…
这里是live example。