Need help logic errors

Pages: 12
I am designing a data structure than can efficiently store and check if total of any three successively added elements is equal to given total.

For example MovingTotal () creates an empty container with no existing totals.append ([1,2,3]) appends elements [1,2,3] which means that there is only one exisitng total (1 + 2 + 3 = 6 ), append ([4]) appends element 4 and creates additional total from [2,3,4]. There would now be two totals (1 + 2 + 3 = 6 and 2 + 3 + 4 = 9). At this point contains (6) and contains (9) should return True, while contains (7) should return False.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <vector>
#include <stdexcept>
#include <iostream>
#include <string>

class MovingTotal{
private:
      std::vector<int> list = std::vector<int>();
public:
     virtual void append(std::vector<int> &list);
     virtual bool contains(int total);
     static void main(std::vector<std::wstring> & args);
};

void MovingTotal::append(const std::vector<int> addAll& list)
{
   list.addAll(Arrays::asList(list));
   throw std::logic_error("Waiting for implement");
}

bool MovingTotal:: contains(int total)
{
  if((list[0] + list[1] + list[2]) == total)
  {

     return true;
  }
  return false;
  throw std::logic_error("Waiting for implement");
}

#ifndef RunTests
int main()
{
   MovingTotal *movingTotal = new MovingTotal();
   movingTotal->append(std::vector<int> {1,2,3});
   std::vector<int> first;
   first.push_back(1);
   first.push_back(2);
   first.push_back(3);
   
   movingTotal->append(first);
   std::wcout << movingTotal->contains(6) << std::endl;
   std::wcout << movingTotal->contains(9) << std::endl;

   std::vector<int> second;
   second.push_back(4);
   movingTotal->append(second);
   std::wcout << movingTotal->contains(9) << std::endl;
}
#endif 




Below are compilation errors:

void MovingTotal::append(const std::vector<int> addAll& list)
^
main.cpp:23:6: error: prototype for ‘void MovingTotal::append(std::vector)’ does not match any in class ‘MovingTotal’
void MovingTotal::append(const std::vector<int> addAll& list)
^~~~~~~~~~~
main.cpp:18:19: error: candidate is: virtual void MovingTotal::append(std::vector&)
virtual void append(std::vector<int> &list);
^~~~~~
main.cpp: In function ‘int main()’:
main.cpp:44:29: error: cannot bind non-const lvalue reference of type ‘std::vector&’ to an rvalue of type ‘std::vector’
movingTotal->append(std::vector<int> {1,2,3});
^~~~~~~~~~~~~~~~~~~
main.cpp:18:19: note: initializing argument 1 of ‘virtual void MovingTotal::append(std::vector&)’
virtual void append(std::vector<int> &list);
^~~~~~

Last edited on
C++ is case sensitive. std::Vector<int> is not a standard type. std::vector<int> is. And either way, you're not consistent.

On line 36, std::vector<int> {1,2,3} is a temporary object, because it doesn't have a name. You can't pass a temporary by non-const reference.
You want
virtual void append(const std::vector<int> &list);

Line 15: Remove the "addAll". Presumably some copy-paste mishap.
void MovingTotal::append(const std::vector<int> & list)

Another issue is line 17. You are trying to add a list to itself...? If the parameter name matches a class identifier, you need to say "this->variable" to differentiate it.
1
2
3
void MovingTotal::append(const std::vector<int>& list)
{
   this->list.addAll(Arrays::asList(list));


Note that standard std::vectors don't have "addAll" as a function, and I don't know what Arrays::asList is. Looks like some Java spinoff.

Other things:

std::vector<int> list = std::vector<int>();This is a bit redundant, since a vector will already by default be constructed in this way.

Your throw statement on line 29 is unreachable code. You're almost certainly meant to remove those exceptions once you implement the code...

Why all the virtual functions? You aren't using polymorphism. If you intend for this class to be used polymorphically, you should have a virtual destructor in your base class.
https://isocpp.org/wiki/faq/virtual-functions#virtual-dtors

Don't be overwhelmed by the number of compiler errors, just look at one at a time, and try to interpret what it's saying.
Last edited on
java has arrays.asList. What is the equivalent in c++? how can I rewrite it using c++?
does c++17 feature Initializer lists? if so how can it be done?
Last edited on
Member initializer lists have been in C++ since the start.
std::initializer_list has been in C++ since C++11.

Consider implementing the logic for "addAll" yourself if you want such functionality.
For example,
1
2
3
4
5
6
7
void addAll(std::vector<int>& vec, const std::vector<int>& addition)
{
    for (const auto& element : addition)
    {
        vec.push_back(element);
    }
}


The more elegant way to do it is: https://stackoverflow.com/questions/201718/concatenating-two-stdvectors
vector1.insert( vector1.end(), vector2.begin(), vector2.end() );
Last edited on
As suggested by you, i made below changes in code, but still has issues with compilation. how can I replace Arrays::asList? there is Arrays::asList only in java and not c++.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <vector>
#include <stdexcept>
#include <iostream>
#include <string>

class MovingTotal{
private:
      std::vector<int> list = std::vector<int>();
public:
     virtual void append(const std::vector<int> &list);
     virtual bool contains(int total);
     static void main(std::vector<std::wstring> & args);
};

void addAll(std::vector<int>& vec, const std::vector<int>& addition)
{
    for (const auto& element : addition)
    {
        vec.push_back(element);
    }
}

void MovingTotal::append(const std::vector<int> &list)
{
   this->list.addAll(Arrays::asList(list));
   throw std::logic_error("Waiting for implement");
}

bool MovingTotal:: contains(int total)
{
  if((list[0] + list[1] + list[2]) == total)
  {

     return true;
  }
  return false;
  
  throw std::logic_error("Waiting for implement");
}

#ifndef RunTests
int main()
{
   MovingTotal *movingTotal = new MovingTotal();
   movingTotal->append(std::vector<int> {1,2,3});
   std::vector<int> first;
   first.push_back(1);
   first.push_back(2);
   first.push_back(3);
   
   movingTotal->append(first);
   std::wcout << movingTotal->contains(6) << std::endl;
   std::wcout << movingTotal->contains(9) << std::endl;

   std::vector<int> second;
   second.push_back(4);
   movingTotal->append(second);
   std::wcout << movingTotal->contains(9) << std::endl;
}
#endif 


main.cpp:33:15: error: ‘class std::vector’ has no member named ‘addAll’
    this->list.addAll(Arrays::asList(list));
               ^~~~~~
main.cpp:33:22: error: ‘Arrays’ has not been declared
    this->list.addAll(Arrays::asList(list));
                      ^~~~~~
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <vector>
using namespace std;

bool movingTotal( const vector<int> &V, int length, int target )
{
   if ( length > V.size() ) return false;
   int sum = 0;
   for ( int i = 0; i < length; i++ ) sum += V[i];
   if ( sum == target ) return true;
   for ( int i = 0, j = length; j < V.size(); i++, j++ ) 
   {
      sum += V[j] - V[i];
      if ( sum == target ) return true;
   }
   return false;
}

int main()
{
   vector<int> V = { 1, 2, 3, 4 };
   for ( int i = 5; i <= 10; i++ ) cout << i << ": " << boolalpha << movingTotal( V, 3, i ) << '\n';
}
Perhaps:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <vector>
#include <iostream>
#include <initializer_list>
#include <iomanip>

class MovingTotal {
private:
	std::vector<int> list;

public:
	void append(const std::initializer_list<int>& list);
	bool contains(int total);
};

void MovingTotal::append(const std::initializer_list<int>& addition)
{
	list.insert(list.end(), addition.begin(), addition.end());
}

bool MovingTotal::contains(int total)
{
	for (int i = 0; i < list.size() - 2; ++i)
		if (list[i] + list[i + 1] + list[i + 2] == total)
			return true;

	return false;
}

int main()
{
	MovingTotal movingTotal;

	std::cout << "Add 1 2 3\n";
	movingTotal.append({1, 2, 3});

	std::cout << "Contains 6 " << std::boolalpha << movingTotal.contains(6) << '\n';
	std::cout << "Contains 9 " << std::boolalpha << movingTotal.contains(9) << '\n';

	std::cout << "Add 4\n";
	movingTotal.append({4});
	std::cout << "Contains 9 " << std::boolalpha << movingTotal.contains(9) << '\n';
}



Add 1 2 3
Contains 6 true
Contains 9 false
Add 4
Contains 9 true

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <algorithm>
#include <array>
#include <iostream>
#include <iterator>
#include <numeric>
#include <unordered_set>

int constexpr window_size = 3;

int main()
{
  std::array xs { 1, 2, 3, 4, 5 };
  std::unordered_set<int> sums;
  
  auto const begin  = xs.begin();
  auto const end    = xs.end();
  auto window_begin = begin;
  auto window_end   = begin + window_size;
  auto out          = std::inserter(sums, sums.end());
  auto sum          = std::accumulate(window_begin, window_end, 0);
  
  sums.insert(sum);
  std::transform(window_end, end, window_begin, out, 
    [sum](auto a, auto b) mutable { return sum += a - b; });
  
  for (int sum: sums) std::cout << sum << '\n';
}
Last edited on
Hi lastchance

I have run your code and it output the below info

8: false
9: true
10: false

In the movingTotal () creates an empty container with no existing totals.append ([1,2,3]) appends elements [1,2,3] which means that there is only one exisitng total (1 + 2 + 3 = 6 ), append ([4]) appends element 4 and creates additional total from [2,3,4]. There would now be two totals (1 + 2 + 3 = 6 and 2 + 3 + 4 = 9). At this point contains (6) and contains (9) should return True, while contains (7) should return False.
@denver,
I wrote a function to see if, for a given vector, some rolling sum of a given length met a given target. I'm not sure why you need to create another entity to match std::vector as that already exists.

If you want the collection of all the sums then you can do as in @mbozzi's code. I'm not sure what you want, as your container doesn't possess any means of storing the sums - just the vector which is simply duplicating the functions of std::vector.

It looks suspiciously as if you are trying to convert code in java (which is entirely object-oriented) to c++ (which is a multi-paradigm language).
Last edited on
I am not porting anything from JAVA, but took it as a reference for this implementation. But having some issues with my code and it doesn't work.
Not a class (too lazy) but ... easy enough to adapt:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <vector>
#include <iostream>
#include <algorithm>

int main()
{
    std::vector<int> m_vector;
    
    int moving_total{0};
    std::vector<int> m_total;
    
    int input{0};
    int temp{0};
    
    while(
          std::cout << "Enter an integer: " &&
          std::cin >> input
          )
    {
        m_vector.push_back(input);
        
        moving_total = 0;
        if(m_vector.size() > 2)
        {
            for (size_t i = 3; i > 0;  i--)
            {
                temp = m_vector.at(m_vector.size() - i);
                moving_total += temp;
                std::cout << ' ' << temp;
            }
            std::cout << " Moving total: " << moving_total << '\n';
            
            std::vector<int>::iterator it;
            
            it = find (m_total.begin(), m_total.end(), moving_total);
            if (it != m_total.end())
                std::cout << "True " << *it << " found\n";
            else
                std::cout << "False\n";
            
            m_total.push_back(moving_total);
        }
    }
}

Enter an integer: 1
Enter an integer: 2
Enter an integer: 3
 1 2 3 Moving total: 6
False
Enter an integer: 4
 2 3 4 Moving total: 9
False
Enter an integer: 2
 3 4 2 Moving total: 9
True 9 found
Enter an integer: 0
 4 2 0 Moving total: 6
True 6 found
Enter an integer: 3
 2 0 3 Moving total: 5
False
Enter an integer: 
I am not sure why class is not used here for your logic?
For example in the class MovingTotal () as shown in my above it creates an empty container with no existing totals.append ([1,2,3]) appends elements [1,2,3] which means that there is only one exisitng total (1 + 2 + 3 = 6 ), append ([4]) appends element 4 and creates additional total from [2,3,4]. There would now be two totals (1 + 2 + 3 = 6 and 2 + 3 + 4 = 9). At this point contains (6) and contains (9) should return True, while contains (7) should return False.
Last edited on
> Need help logic errors
> Below are compilation errors:
https://clanguagebasics.com/types-of-errors-in-c/

> static void main(std::vector<std::wstring> & args);
¿what's the purpose of that function?

> virtual bool contains(int total);
¿why virtual?

> java has arrays.asList. What is the equivalent in c++?
¿what does arrays.asList do?

> this->list.addAll(Arrays::asList(list));
¿now you are inventing member function for std::vector? rtfm

> In the movingTotal () creates an empty container with no existing totals...
¿how many times are you going to repeat your assignment?
about lastchance's code, take a guess what `target' means
I am not sure why class is not used here for your logic?

C++ does not require a class like java does. You can write your code the way you want to, rather than forced into a single approach. He said as much, that it was a quick and lazy example that did not bother with a class. Classes require a lot of extra typing and bloat; many simple problems are solved without all that extra stuff when it is not needed. Classes are powerful and do use them if you feel you need one, but feel free to not use them if all you really needed was a function.

I read the documentation, and as far as I can tell, aslist would likely just need to be a copy of a vector into a list in c++ (I think this would mean you need to do a for loop; I don't think there is a cross constructor or anything). But what functionality do you REQUIRE? Do you need something a vector can do and something a list can do that is not supported by both, and if so, what exactly is that need? It would not take but a few lines to wrap a vector up as a list, DIY, and some smoke and mirrors. I prefer this to a normal linked list, because you can tap the underlying vector for serialization and other processes more efficiently, and the list wrapper does not suffer from doing so.
Last edited on
I have no idea about vector and list. All I need is a class which is capable of doing the below functionality. For example in the class MovingTotal () as shown in my above it creates an empty container with no existing totals.append ([1,2,3]) appends elements [1,2,3] which means that there is only one exisitng total (1 + 2 + 3 = 6 ), append ([4]) appends element 4 and creates additional total from [2,3,4]. There would now be two totals (1 + 2 + 3 = 6 and 2 + 3 + 4 = 9). At this point contains (6) and contains (9) should return True, while contains (7) should return False.
do you need how you got the total, or just the total's value as a true/false?

there are lots of ways to do it.
you can do what you said with
class mywhatever
{
vector<int> vi; //this will hold your [1,2,3] or [2,3,4]
int sum; //this will hold the sum
}

which you can search by sum, using whatever ... sort by sum and binary search, for example.
and an outer container, could be anything, of mywhatever class, eg a vector..
vector<mywhatever> mw;

it will take a little setup to get it working but you can certainly set that design up to do what you asked. You can also do something like stuff the sum into the 0th element of the vector instead of its own variable, which can simplify things to a vector of vector without your own class.
there are other ways too.
Last edited on
I need to store and check if total of any three successively added elements is equal to given total.
#include <magic>
What is the usage for #include <magic>? How does it help here?
Pages: 12