【问题标题】:C++: How to use a vector function in a class?C++:如何在类中使用向量函数?
【发布时间】:2016-04-26 21:42:18
【问题描述】:

这个问题 - Two Sum - 来自LeetCode,函数(算法)代码来自here。我曾经在本科时使用 C++。但是我有很长时间没有使用它。我现在正在审查 C++ 的数据结构。我搜索了很多网站来复习 C++ 基础知识。

这是我的代码,我想实现我之前在那个问题中提到的算法。但我不知道我在main 部分的代码有什么问题。

int main()
{
    vector<int> numbers(4);
    int target;
    cout<<"input numbers"<<endl;
    for(int i=0; i<4; ++i)
    cin >> numbers[i];
    cout<<"target"<<endl;
    cin >> target;
    Solution solu;
    solu.twoSum(numbers, target);
    cout << solu.ans << endl;//No member named 'ans' in 'Solution'
}

我使用 Xcode 来运行 C++。有人可以帮我解决这个问题吗?

解决方案here 有错误Control may reach end of non-void function。是因为 Xcode 编译器还是代码有错误?

请详细解释一下。 提前致谢。

【问题讨论】:

  • void main 不是 C++ 标准的一部分。不要使用它,因为您的代码不可移植。
  • int main 是正确且被认可的语法,但它要求main 返回一个整数值。这允许程序向调用您的程序的程序发送一些基本信息。如果您没有任何特定消息要返回给调用者,只需在 main 结尾处 return 0;
  • @user4581301 return 0; 在 main 的末尾是不需要的。根据标准,如果达到main},则将生成隐式return 0;
  • @JW.ZG 我的母语不是英语,所以请随时纠正我。我确实有一个秘密插件来增加声誉。您只需要真正阅读所有内容并了解 Visual Studio 不是参考 C++ 编译器实现。在 VS 中有效并不意味着代码符合 C++ 标准。

标签: c++ xcode algorithm


【解决方案1】:

第 1 点已经讲过了,所以我在回应第 2 点。首先是有问题的代码:

vector<int> twoSum(vector<int>& nums, int target) 
{
    static int MAX = 99999;
    static int DELT = 49999;
    vector<int> ans;
    int x[MAX];
    memset(x, 0, sizeof(x));
    for (int i = 0; i < nums.size(); i++)
    {
        if (x[nums[i] + DELT])
        {
            ans.push_back(((i + 1) < x[nums[i] + DELT] ? 
                                      (i + 1) : x[nums[i] + DELT]));
            ans.push_back(((i + 1) > x[nums[i] + DELT] ? 
                                      (i + 1) : x[nums[i] + DELT]));
            return ans;
        }
        x[target - nums[i] + DELT] = i + 1;
    }
}

请注意,函数中唯一的 return 语句嵌套在 for 循环和 if 语句中。这允许return 语句永远不会到达的可能性,因为没有进入循环或者if (x[nums[i] + DELT]) 永远不会是真的。触发此行为的一种简单方法是输入一个空的nums 向量:

for (int i = 0; i < 0; i++)

永远不会进入循环,也永远不会到达 return 语句。在这种情况下会返回什么?没有人知道,而且每次运行可能都会有所不同。也许程序会崩溃。也许它会扑通一声坐在你的沙发上,一边喝朗姆酒和伏特加一边看亚当·桑德勒的电影马拉松。

“哦,但这永远不会发生!”你说。也许不会,但是当面对严格测试和强制执行的要求时,乐观是一个糟糕的选择。不管编译器是否指出了逻辑中的一个漏洞,这可能会导致很多痛苦和调试,这是一个很容易填补的漏洞

vector<int> twoSum(vector<int>& nums, int target) 
{
    static int MAX = 99999;
    static int DELT = 49999;
    vector<int> ans;
    int x[MAX];
    memset(x, 0, sizeof(x));
    for (int i = 0; i < nums.size(); i++)
    {
        if (x[nums[i] + DELT])
        {
            ans.push_back(((i + 1) < x[nums[i] + DELT] ? 
                                      (i + 1) : x[nums[i] + DELT]));
            ans.push_back(((i + 1) > x[nums[i] + DELT] ? 
                                      (i + 1) : x[nums[i] + DELT]));
            break;
        }
        x[target - nums[i] + DELT] = i + 1;
    }
    return ans;
}

现在总是返回ans,但这允许返回的ans 不包含或处理不正确的信息。不是一个好的答案,因为twoSum 可能不再杀死您的程序,但处理它的输出可以。

bool twoSum(vector<int>& nums, int target, vector<int> &ans) 
{
    static int MAX = 99999;
    static int DELT = 49999;
    int x[MAX];
    memset(x, 0, sizeof(x));
    for (int i = 0; i < nums.size(); i++)
    {
        if (x[nums[i] + DELT])
        {
            ans.push_back(((i + 1) < x[nums[i] + DELT] ? 
                                      (i + 1) : x[nums[i] + DELT]));
            ans.push_back(((i + 1) > x[nums[i] + DELT] ? 
                                      (i + 1) : x[nums[i] + DELT]));
            return true;
        }
        x[target - nums[i] + DELT] = i + 1;
    }
    return false;
}

twoSum 仅在达到退出条件时才返回true。如果它返回false,则不能信任ans 的内容。需要对算法进行更多工作以确保 ans 始终完整且正确,或者需要将 twoSum 包装在另一个函数中,该函数在执行前验证输入。

【讨论】:

  • 谢谢,但我的问题更多的是关于main 部分。我不知道如何在 main.js 中实现它。我发现vector&lt;int&gt; numbers的值很难输入,因为输入的数量不固定,可能是4个数字,5个、6个或更多。如何在没有固定内存的情况下实现输入功能?我的意思是向量的长度不是固定的。
  • @JW.ZG 如果您在输入时遇到问题,为什么您没有提到它?要实现这样的输入,您需要向用户询问数字计数并循环输入它们。或者只是要求循环中的数字并使用数字缺失作为序列的结尾。
  • @JW.ZG 读取任意数量的数字需要一些不同的想法。而不是cin &gt;&gt; numbers[i];,您想要cin &gt;&gt; temp; numbers.push_back(temp) 并测试所需的任何退出条件,无论是用户想要退出时可以输入的某种“金丝雀”值,还是Michael Nastenko 建议并提前询问用户时间他们希望输入多少值。 push_back 允许向量在添加更多值时自行调整大小。最大大小通常是您拥有多少 RAM 的函数。
  • 非常感谢。我明白了。对不起,但我想我已经写了我的问题的解释。这个问题我想了很久。我记得我在某处写了具体的解释......我搞砸了。再次感谢。
猜你喜欢
  • 2015-04-30
  • 2018-06-20
  • 2016-10-01
  • 2021-03-15
  • 1970-01-01
  • 2022-01-12
  • 1970-01-01
  • 2023-04-09
  • 1970-01-01
相关资源
最近更新 更多