【问题标题】:C++ Remove the last new lineC++ 删除最后一个新行
【发布时间】:2013-05-01 11:06:41
【问题描述】:

我正在使用coutendl 打印一些指南,输出(我的意图)如下:

From Spot 1
Spot 2
Spot 5
Spot 8
Spot 6
To Spot 3

这里,Spot No. 是随机的,是通过一些迭代生成的。由于迭代,我只能打印如下结果:

From Spot 1
Spot 2
Spot 5
Spot 8
Spot 6
Spot 3

有什么方法可以删除我最后的新行Spot 3

编辑:

我想找到两个顶点之间的最短路径(使用 Floyd-Warshall 算法)。这是我的代码,它描述了以下图形:

#include <iostream>
using namespace std;

const int INF = 100000;
int n = 10, path[11][11], dist[11][11], map[11][11];
void init() {
    int i, j;
    for ( i = 1; i <= n; i++ )
        for ( j = 1; j <= n; j++ )
            map[i][j] = ( i == j ) ? 0:INF;
    map[1][2] = 2, map[1][4] = 20, map[2][5] = 1;
    map[3][2] = 3, map[4][3] = 8, map[4][6] = 6;
    map[4][7] = 4, map[5][3] = 7, map[5][8] = 3;
    map[6][3] = 1, map[7][8] = 1, map[8][6] = 2;
    map[8][10] = 2, map[9][7] = 2, map[10][9] = 1;
}
void floyd() {
    int i, j, k;
    for ( i = 1; i <= n; i++ )
        for ( j = 1; j <= n; j++ )
            dist[i][j] = map[i][j], path[i][j] = 0;
    for ( k = 1; k <= n; k++ )
        for ( i = 1; i <= n; i++ )
            for ( j = 1; j <= n; j++ )
                if ( dist[i][k] + dist[k][j] < dist[i][j] )
                    dist[i][j] = dist[i][k] + dist[k][j], path[i][j] = k;
}
void output( int i, int j ) {
    if ( i == j ) return;
    if ( path[i][j] == 0 ) cout << "Spot" << j << endl;
    else {
        output( i, path[i][j] );            // iterations
        output( path[i][j], j );
    }
}
int main() {
    int u, v;
    init();
    floyd();
    u = 1, v = 3;
    if ( dist[u][v] == INF ) cout << "No path" << endl;
    else {
        cout << "From Spot" << u << endl;
        output( u, v );
        cout << endl;
    }
    return 0;
}

现在的问题是找到最后一次迭代的条件,以便我可以cout 一个不同的表达式。但是我认为通过简单地删除最后一个表达式并重写来解决问题更容易,所以我没有附上我的代码。

编辑 2:

在 Fabian Tamp 的帮助下,我已经实现了我的目的,尽管我编写上面的代码似乎有点愚蠢。修改后的代码如下:

#include <iostream>
#include <queue>
using namespace std;

const int INF = 100000;
int n = 10, path[11][11], dist[11][11], map[11][11];
void init() {
    int i, j;
    for ( i = 1; i <= n; i++ )
        for ( j = 1; j <= n; j++ )
            map[i][j] = ( i == j ) ? 0:INF;
    map[1][2] = 2, map[1][4] = 20, map[2][5] = 1;
    map[3][3] = 3, map[4][3] = 8, map[4][6] = 6;
    map[4][7] = 4, map[5][3] = 7, map[5][8] = 3;
    map[6][3] = 1, map[7][8] = 1, map[8][6] = 2;
    map[8][10] = 2, map[9][7] = 2, map[10][9] = 1;
}

void floyd() {
    int i, j, k;
    for ( i = 1; i <= n; i++ )
        for ( j = 1; j <= n; j++ )
            dist[i][j] = map[i][j], path[i][j] = 0;
    for ( k = 1; k <= n; k++ )
        for ( i = 1; i <= n; i++ )
            for ( j = 1; j <= n; j++ )
                if ( dist[i][k] + dist[k][j] < dist[i][j] )
                    dist[i][j] = dist[i][k] + dist[k][j], path[i][j] = k;
}

void output( int i, int j, queue<int> &output_queue ) {
    if ( i == j ) return;
    if ( path[i][j] == 0 ) output_queue.push(j);
    else {
        output( i, path[i][j], output_queue);            // iterations
        output( path[i][j], j, output_queue);
    }
}

void print_path(queue<int> output_queue) {
    if (output_queue.empty()) return;
    int item = output_queue.front();
    while (!output_queue.empty()) {
        item = output_queue.front();
        output_queue.pop(); 
        if (output_queue.empty()) {
            cout << "To ";
        } 
        cout << "Spot " << item << endl;
    }
}
int main() {
    int u, v;
    init();
    floyd();
    u = 1, v = 3;
    if ( dist[u][v] == INF ) cout << "No path" << endl;
    else {
        cout << "From Spot " << u << endl;
        queue<int> output_queue;
        output(u, v, output_queue);
        print_path(output_queue);
    }
    return 0;
}

输出是一开始的指南。谢谢大家!

【问题讨论】:

  • 它可以帮助我们查看代码,以便我们可以帮助您更正它。
  • 这些是通过迭代生成的,然后您可以在最后一次迭代中添加条件以根据您的意图进行打印。
  • @sftrabbit 代码添加

标签: c++ graph shortest-path


【解决方案1】:

因此改变你的输出功能:

void output( int i, int j, Queue<int> &output_queue ) {
    if ( i == j ) return;
    if ( path[i][j] == 0 ) output_queue.push(j);
    else {
        output( i, path[i][j], output_queue);            // iterations
        output( path[i][j], j, output_queue);
    }
}

然后更改您的main()

//....
else {
    Queue<int> output_queue;
    output_queue.push(u);
    output(u, v, output_queue);
    print_path(output_queue);
}
//...

然后添加print_path:

void print_path(Queue<int> output_queue) {
    if (output_queue.empty()) return;

    auto item = output_queue.front();
    cout << "From Spot "  << item << endl;

    while (!output_queue.empty()) {
        item = output_queue.front();
        output_queue.pop();

        if (output_queue.empty()) {
            cout << "To ";"
        }
        cout << "Spot " << item << endl;
    }

}

这里有几件事:

  • 我还没有编译或测试过这个。尝试自己找出任何错误,并在 cmets 中告诉我。
  • 查看 STL 对您非常有帮助。 http://www.cplusplus.com/reference 是一个很好的资源。
  • 如果您不熟悉通过引用传递,这是我用来确保我们将信息添加到同一个output_queue 的策略。请注意,我通过 copy 传递了print_path(),因为它破坏了参数中的数据。它是 C++ 中最强大的技术之一。

【讨论】:

  • 除了end() 一般是不可递增的。
  • @Angew - 你是对的;我想写的是for (auto x = iterable.begin(); x + 1 != iterable.end(); ++x)
  • @FabianTamp - 我厌倦了通过添加#include &lt;queue&gt; 并使用queue&lt;int&gt; 而不是Queue&lt;int&gt; 来修复错误。最后,它在函数print_path() 中有一个关于auto item 的错误:错误C4430:缺少类型说明符-假定为int。注意:C++ 不支持默认整数。把auto改成int可以吗?如果我这样做,虽然编译成功,但打印输出是From Spot 2,超出预期。
  • 好的,你需要将你的第一个打印语句的等价物添加到队列中,见上面代码中的output_queue.push(u);
  • @FabianTamp - 谢谢!实际上,循环条件应该是while (!output_queue.empty()),如我第二次编辑的那样,否则它不会跳入循环并打印以下内容。
【解决方案2】:

如果你打印了多少行,你可以使用这个宏

#define gotoxy(a,b) {COORD coord; coord.X=(b); coord.Y=(a) ; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);}

然后转到该行并为您打印的所有字符打印“”。

【讨论】:

  • 这在我看来不像 C++(该语言没有 SetConsoleCursor 之类的东西......而且 OP 没有说明正在使用哪个平台)。
【解决方案3】:

如果您不在每行之后打印换行符,它会更容易。然后,您可以返回并“擦除”当前行上的文本,方法是输出与该行字符数相等的“\b”(退格)字符,后跟相同数量的空格(以清除在那里)。然后你可以通过写“\r”回到行首,重新写整行。

【讨论】:

  • 谢谢约翰!但是我怎样才能将所有的 '\r' 插入它们曾经所在的位置呢?
  • 我不明白你的问题。但无论如何,既然您已经发布了更多代码,我认为像 Fabian 的想法可能会更容易。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-13
  • 2014-05-22
  • 1970-01-01
相关资源
最近更新 更多