【问题标题】:Which solution is optimal?哪种解决方案是最优的?
【发布时间】:2021-11-02 00:41:15
【问题描述】:

我有两个解决这个问题的方法,但哪一个是最佳的?

给出了 N 个数字的列表。玩家必须排列数字,以使列表中的所有奇数都排在偶数之后。编写一个算法来排列给定的列表,使得列表的所有奇数都排在偶数之后。

输入

输入的第一行由一个整数组成,表示列表的大小(N)。 输入的第二行由 N 个空格分隔的整数组成,表示列表的值

输出

打印 N 个以空格分隔的整数,使得列表的所有奇数都排在偶数之后

示例

示例输入

8
10 98 3 33 12 22 21 11

样本输出

10 98 12 22 3 33 21 11

解决方案 1-

    #include<bits/stdc++.h>
using namespace std;

int main(){
    
    int n;
    cin>>n;
    
    int a[n];
    
    for(int i=0; i<n; i++)
      cin>>a[i];
      
    
    int p1=0, p2= n-1;
    
    while(p1 < p2){
        
        while(a[p1]%2 == 0 and p1<p2)
           p1++;
        
        while(a[p2]%2 != 0 and p1<p2)    
           p2--;
        
        if(p1 < p2){
            swap(a[p1], a[p2]);
            p1++;
            p2--;
        }
    }
    
    
    for(int i=0; i<n; i++)
     cout<<a[i]<<" ";
    
    return 0;
}

解决方案 2-

#include <iostream>

using namespace std;

int main()
{
    int n;
    cin>>n;
    int arr[n];

    for(int i=0;i<n;i++){
        cin>>arr[i];
    }
    
    for(int i=0;i<n;i++){
        if(arr[i]%2==0)
        cout<<arr[i]<<" ";
    }
    for(int i=0;i<n;i++){
        if(arr[i]%2!=0)
        cout<<arr[i]<<" ";
    }
    

    return 0;
}

【问题讨论】:

  • 两者都无效,cin&gt;&gt;n; int arr[n]; 不是标准 C++。
  • @JosephLarson 确实,任何版本的 C++ 都不支持 VLA。
  • 澄清您对“最佳”的定义。您是在谈论内存中的最佳大小吗?最佳性能?最佳可读性?最佳稳健性?最佳的维护便利性?问题太多,时间太少了。
  • 您可能想做的是查看std::partition。正如您在可能的实现中看到的那样,只需要一个循环。
  • @JosephLarson 是的,N3690 包含对此的建议,但最终没有成功。请参阅 this answerthis overview。所以这篇文章只是链接到了不正确的、未完成的标准版本。

标签: c++ numbers


【解决方案1】:
#include <iostream>

using namespace std;

int main()
{
    int n;
    cin >> n;
    int* arr = new int[n];
    int* odd = new int[n];
    int* even = new int[n];
    int oddIndex = 0;
    int evenIndex = 0;

    for(int i=0;i<n;i++){
        cin>>arr[i];
    }
    
    for(int i=0;i<n;i++){
        if(arr[i]%2==0)
            even[evenIndex++] = arr[i];
        else
            odd[oddIndex++] = arr[i];
    }

    for(int i=0;i<evenIndex;i++){
        cout<<even[i]<<" ";
    }

    for(int i=0;i<oddIndex;i++){
        cout<<odd[i]<<" ";
    }
    

    return 0;
}

【讨论】:

    【解决方案2】:

    我会做一些更改,但主要遵循第二个示例。

    首先,我会放入一个 if 语句来确保 n 是一个正数。这只是一个很好的检查。

    接下来,我不会像这样输出它们。我会构建第二个数组。

    int inputArray[n];
    int finalArray[n];
    int outputIndex = 0;
    
    ... Fill inputArray like you currently fill array
    
    for (int i = 0; i < n; ++i) {
        if (inputArray[i] % 2 == 0) {
            outputArray[outputIndex++] = inputArray[i];
        }
    }
    

    以同样的方式执行第二个循环。然后转储 outputArray。

    现在,还有一些其他说明。这些是风格,但会帮助你。请在您的代码中使用更多空格。请注意,我的代码在运算符之间有空格。你显然很年轻,眼睛很年轻,但是当你不得不与老屁共享代码时,现在的好习惯很重要。你的代码真的很难阅读,而且很容易隐藏错误。你不会相信代码中有多少错误,因为有些程序员害怕空格。

    其次,许多程序员会告诉您,不应将可选大括号视为可选的。注意我的 if 语句有一对大括号,而你的没有。如果你看看你的代码是如何格式化的,你会发现你的缩进是错误的。你没有正确缩进你的 cout 行。这是错误隐藏的一种方式。如果你总是使用大括号,即使语言认为它们是可选的,你的错误也会更少。

    最后,大多数人会建议你停止使用定长数组,而改用向量,但作为一个新程序员,你可能还没有准备好。

    【讨论】:

    • 这不是 C++,它仍然是 C。因为 n 仅在运行时可用,而不是在编译时可用。在 C++ 中,你需要 std::vector
    • 由于 array[n] 是可变长度数组 (VLA),并且不受 标准 C++ 支持,我建议将它们替换为 std::vector
    • @PKramer 请阅读 C++ 14 标准第 184 至 185 页。isocpp.org/files/papers/N3690.pdf。第 185 页的顶部有一个使用非常量 int 作为数组大小的示例。但你会注意到我最后还告诉他使用 std::vector。
    • @ThomasMatthews 查看我对 PKramer 的评论。
    • @JosephLarson 论文 N3690 似乎是 C++14 之前的草案,参考了未被接受的 VLA 提案。最终标准不支持 VLA。 stackoverflow.com/questions/60566659/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-27
    • 2014-03-24
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 2010-11-28
    • 1970-01-01
    相关资源
    最近更新 更多