-3

This question - Two Sum - is from LeetCode, and the function(algorithm) code is from here. I used to use C++ in my undergraduate. But I have a long time not using it. I am reviewing the data structure of C++ now. I have search many and many websites to review the C++ basic knowledge.

Here is my code, I want to implement the algorithm I mentioned before in that question. But I don't know what is wrong with my code in the main part.

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'
}

I use Xcode to run C++. Can someone help me with this question?

The solution here has error, Control may reach end of non-void function. Is it because of Xcode compiler or it do has error in code?

Please explain this detailedly. Thanks in advance.

JW.ZG
  • 481
  • 5
  • 17
  • 1
    1. http://stackoverflow.com/questions/204476/what-should-main-return-in-c-and-c 2. you need to return – Bryan Chen Jan 20 '16 at 20:55
  • 1
    `void main` is not a part of the C++ standard. Do not use it because your code will not be portable. – user4581301 Jan 20 '16 at 20:55
  • 1
    `int main` is the correct and approved syntax, but it requires `main` to return an integer value. This allow the program to signal some basic information to the program that calls your program. If you don't have any particular messages to return to the caller, just `return 0;` at the end of main. – user4581301 Jan 20 '16 at 20:58
  • 2
    @user4581301 `return 0;` at the end of main is not needed. Per the standard if the `}` of `main` is reached an implicit `return 0;` will be generated. – NathanOliver Jan 20 '16 at 21:06
  • @NathanOliver Yeah, I just reread the question and looked at the linked code. I like the explicit `return 0;`, but that's a taste thing. – user4581301 Jan 20 '16 at 21:45
  • 1
    @JW.ZG I am not native English speaker so feel free to correct me. I do have a secret plug-in to increase reputation. You just need to really read everything and understand Visual Studio is _not_ the reference C++ compiler implementation. It works in VS doesn't mean the code conform to C++ standard. – Bryan Chen Jan 21 '16 at 01:05

1 Answers1

2

Point 1 has already been covered, so I'm responding to point 2. First the code in question:

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;
    }
}

Note that the only return statement in the function is nested inside a for loop and an if statement. This allows for the possibility that the return statement never reached because the loop was not entered entered or if (x[nums[i] + DELT]) was never be true. One easy way to trigger this behaviour is to input an empty nums vector:

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

Will never enter the loop and never reach the return statement. What will be returned in this case? No one knows, and it may be different with every run. Maybe the program will crash. Maybe it will plop down on your sofa an watch an Adam Sandler movie marathon while drinking rum and vodka.

"Oh, but this will never happen!" you say. Maybe it won't, but optimism is a poor choice when set against rigorously tested and enforced requirements. Regardless the compiler is pointing out a hole in the logic that could result in much pain and debugging, and this is a hole that can easily be filled

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;
}

Now return ans is always reached, but this allows for the possibility that the returned ans contains no or incorrectly processed information. Not a good answer as twoSum may no longer kill your program, but processing its output could.

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 returns true only if the exit condition was reached. If it returns false the contents of ans cannot be trusted. More work on the algorithm is required to ensure that ans is always complete and correct or twoSum needs to be wrapped in another function that validates the inputs before executing.

user4581301
  • 29,019
  • 5
  • 26
  • 45
  • Thank you, but my question is more about the `main` part. I don't know how to implement it in main. I find it is hard to input the values of `vector numbers`, because the number of the input is not fixed, it could be 4 numbers, 5, 6, or more. How to implement the input function without a fixed memory? I mean the length of the vector is not fixed. – JW.ZG Jan 21 '16 at 00:39
  • @JW.ZG If you have problems with input why didn't you mentioned it in question? To implement such input you need to ask user about numbers count and input them in loop. Or just ask for number in loop and use number absence as end of sequence. – Michael Nastenko Jan 21 '16 at 01:36
  • @JW.ZG reading in an arbitrary number of numbers requires a bit of different thinking. Rather than `cin >> numbers[i];`, you want `cin >> temp; numbers.push_back(temp)` and a test for whatever exit condition is required, be it some sort of "canary" value the user can enter when they want to quit or what Michael Nastenko suggested and asking the user ahead of time how many values they wish to input. [`push_back`](http://en.cppreference.com/w/cpp/container/vector/push_back) allows the vector to resize itself as more values are added. The max size is typically a function of how much RAM you have. – user4581301 Jan 21 '16 at 02:26
  • Thank you very much. I got the point. I'm sorry but I thought I have written the explanation of my question. I have thought about this question for a very long time. I remember I wrote the specific explanation somewhere... I messed it up. Thanks again. – JW.ZG Jan 21 '16 at 03:01