Non empty list when passed to function becomes empty - c++

So I got this code. The problem is that with a for loop I create empty lists and add to them 1 integer. Then I pass the list to the DFS function and it says that the list is empty. Any ideas why this is happening?
#include <list>
#include<vector>
#include <iostream>
using namespace std;
list<short> integer;
vector<list<short> > all;
void DFS(list<short> ingeter, int N)
{
if(integer.empty())
{
cout<<"IT IS EMPTY"<<endl;
return;
}
if(integer.size() > N || (integer.size() > 0 && (integer.front() == 0 || integer.back() % 2 == 0)))
{
return;
}
cout<<"size: "<<integer.size()<<endl;
all.push_back(integer);
for(short i = 0; i <= 9; ++i)
{
integer.push_back(i);
integer.push_front(i);
DFS(integer, N);
integer.pop_back();
integer.pop_front();
}
}
int main()
{
int N = 8;
for(short i = 0; i <= 9; ++i)
{
list<short> current;
current.push_back(i);
cout<<"size: "<<current.size()<<endl;
DFS(current, N);
}
return 0;
}

The problem is you are accessing the wrong variable. You named the parameter ingeter but your function is accessing integer which is a global variable.
void DFS(list<short> ingeter, int N)
// ^^^^^^^
{
if(integer.empty())
// ^^^^^^^
{
//...
}
}

Related

MayI know why this code is not giving any output?

Please help me to solve the query that this code runs infinitely at a particular line.
It does not give any output as at the end of the code I write the code to print the vector. Even after I assign any value to vector "result" manually still it is not giving any output. why is it so?
#include<bits/stdc++.h>
using namespace std;
bool authorize(int strValue, int value, int M)
{
long int newValue = (strValue - (value * 131) % M);
if (newValue >= 48 && newValue <= 57)
return true;
if (newValue > 65 && newValue <= 90)
return true;
if (newValue >= 97 && newValue <= 122)
return true;
return false;
}
int hashingfunct(string str, int M)
{
long int P, F, sum = 0;
int len = str.length();
for (int i = 0; i < len; i++)
{
P = pow(131, len - i - 1);
F = (int)str[i];
sum += (F * P) % M;
}
sum = sum % M;
return sum;
}
int main()
{
int n = 5;
string str1, str2;
vector<vector<string> > events;
for (int i = 0; i < n; i++) {
cin >> str1 >> str2;
vector<string > temp;
temp.push_back(str1);
temp.push_back(str2);
events.push_back(temp);
}
for (int i = 0; i < n; i++) {
cout << events[i][0] << events[i][1];
}
/*
INPUT FORMAT:
setpassword 1
setpassword 2
setpassword 3
authorize 49
authorize 50
*/
vector<int> result;
int j = 0;
long int m = pow(10, 9);
long int M = m + 7;
long int value, strValue;
for (int i = 0; i < events.size(); i++)
{
strValue = stoi(events[i][1]);
if (events[i][0] == "setPassword") {
value = hashingfunct(events[i][1], M);
}
else if (strValue == value)
result[j++] = 1;
else if (authorize(strValue, value, M))
result[j++] = 1;
else
result[j++] = 0;
}
for (int i = 0; i < result.size(); i++) {
cout << result[i];
}
}
Your program has complete Undefined Behaviour.
Let's get started with the first problem. In the following check code
long int value, strValue; // not initialised
for (int i = 0; i < events.size(); i++)
{
// ...
// here it should have been "setpassword" (i.e. all are small letters)
if (events[i][0] == "setPassword")
{
// if the check fails the `value` never get initialised!
value = hashingfunct(events[i][1], M);
}
// If the `value` not been initialised, check happens with any garbage value here!
else if (strValue == value)
// ...other code
}
You are checking whether the string is "setPassword" instead of "setpassword" (i.e. see in the events vector, all the strings are small letters).
If that goes wrong, the value will never get initialized, meaning it holds any garbage value and hence conducting this check else if (strValue == value) can cause any behaviour to your program (aka Undefined Behaviour).
Secondly, the vector<int> result; is empty at the beginning. Therefore accessing elements via std::vector::operator[] later
result[j++] = 1;
// ...
result[j++] = 1;
// ...
result[j++] = 0;
triggers the access out of bounds (UB). There you need just result.emplace_back(/*value*/); or result.push_back(/*value*/);, and no need of redutant variable j.
In short, you need
#include <iostream>
#include <vector>
#include <string>
// ..other functions
int main()
{
std::vector<std::vector<std::string> > events {
{"setpassword", "1"}, // can be also user input, like in your example
{"setpassword", "2"},
{"setpassword", "3"},
{"authorize", "49" },
{"authorize", "50" }
};
std::vector<int> result;
const long int M = pow(10, 9) + 7;
long int value{ 0 }, strValue{ 0 }; // default initialization
for (const std::vector<std::string> row: events) // better use range-based loop
{
strValue = std::stoi(row[1]);
if (row[0] == "setpassword") {
value = hashingfunct(row[1], M);
if (strValue == value)
result.emplace_back(1);
else if (authorize(strValue, value, M))
result.emplace_back(1);
}
else
result.emplace_back(0);
}
}
As a side note,
Please do not use using namespacestd;
Why should I not #include <bits/stdc++.h>?
Corrected code
#include<bits/stdc++.h>
using namespace std;
bool authorize(long int strValue,long int value,int M){
long int value1=value*131;
long int newValue=(strValue-(value1%M))%M;
if(newValue>=48 && newValue<=57)
return true;
if(newValue>=65 && newValue<=90)
return true;
if(newValue>=97 && newValue<=122)
return true;
return false;
}
int hashingfunct(string str,int M){
long int P,F,sum=0;
int len=str.length();
for(int i=0;i<len;i++){
P=pow(131,len-i-1);
F=(int)str[i];
sum+=(F*P)%M;
}
sum=sum%M;
return sum;
}
int main(){
int n=5;
string str1,str2;
vector<vector<string> > events;
for (int i=0;i<n;i++){
cin>>str1>>str2;
vector<string > temp;
temp.push_back(str1);
temp.push_back(str2);
events.push_back(temp);
}
/*
setPassword cAr1
authorize 223691457
authorize 303580761
setPassword d
authorize 100
*/
vector<int> result;
int j=0;
long int m=pow(10,9);
long int M=m+7;
long int value,strValue;
for(int i=0;i<events.size();i++){
if(events[i][0]=="setPassword"){
value=hashingfunct(events[i][1],M);
continue;
}
strValue=stoi(events[i][1]);
if(strValue==value)
result.push_back(1);
else if(authorize(strValue,value,M))
result.push_back(1);
else
result.push_back(0);
}
for(int i=0;i<result.size();i++){
cout<<result[i];
}
}

Function, which outputs the sum of the digits of an integer in C++?

I have written a function that ought to print the sum of all digits of a given integer. However the program outputs incorrect result, it should output 19. I want to ask why this happens? The program outputs 2686935.
#include <iostream>
#include <vector>
using namespace std;
vector <int> a;
int sumDigits(int n)
{
int tmp;
if((n>1 && n<9) || n==1 || n==9)
{
tmp=n;
return tmp;
}
while(n>9)
{
a.push_back(n%10);
n/=10;
if((n>1 && n<9) || n==1 || n==9)
{
a.push_back(n);
}
}
for(int i=0; i<a.size(); i++)
{
tmp+=a[i];
}
return tmp;
}
int main()
{
cout<<sumDigits(12745);
return 0;
}
It's way too complex. This should work (except for negative numbers)
int sumDigits(int n)
{
int total = 0;
while (n > 0)
{
total += n%10;
n /= 10;
}
return total;
}
Combination of n%10 and n/10 in a loop gives you each digit in the number, then just add them up.
The error in your original code is that tmp is not initialised to zero.
int tmp = 0;
remember that inside a function, tmp will not be initialized by default!
you forgot to init sum to 0 (sum = 0;)
#include <iostream>
using namespace std;
int sumDigits(int n)
{
int tmp = 0;
while(n>0) {
tmp+=n%10;
n/=10;
}
return tmp;
}
int main()
{
cout<<sumDigits(12745);
return 0;
}
Your implementation of sumDigits doesn't initialize tmp if n>9, which fits exactly the case covered by your example. Therefore, tmp+=a[i] keeps on adding stuff to an integer filled with garbage.
You must set the tmp variable as 0
Here is your corrected code:
#include <iostream>
#include <vector>
using namespace std;
vector <int> a;
int sumDigits(int n)
{
int tmp=0;
if((n>1 && n<9) || n==1 || n==9)
{
tmp=n;
return tmp;
}
while(n>9)
{
a.push_back(n%10);
n/=10;
if((n>1 && n<9) || n==1 || n==9)
{
a.push_back(n);
}
}
for(int i=0; i<a.size(); i++)
{
tmp+=a[i];
}
return tmp;
}
int main()
{
cout<<sumDigits(12745);
return 0;
}

Subgraph with max nodes

I have the graph with N nodes. I have to create the longest subgraph (with max nodes). One node can be connected with only 2 nodes. So which nodes should I take to create this (max) subgraph?
What I'm doing is:
1: From initial node. I start 2 DFS functions. (from anothers nodes only 1).
2: For some node in DFS I use F() function to check all neighbours and find maximum way that I have to go. Then I'm saving the index of the node in which I have to go in index variable and starting DFS from index.
The problem is that this algorithm is too slow. How can I optimize it? Maybe there is special algorithm to find maximum subgraph?
Here is my code:
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
int used[20];
int m[20][20];
int c;
int F(int v) {
used[v] = 1;
int maxn = 0, index = -1, t;
for(int i = 0; i < c; ++i) {
if(!used[i] && m[v][i] == 1) {
t = F(i);
if(t > maxn) {
maxn = t;
index = i;
}
}
}
if(index != -1) {
used[v] = 0;
return maxn + 1;
}
else {
used[v] = 0;
return 1;
}
}
int DFS(int v) {
used[v] = 1;
int maxn = 0, index = -1, t;
for(int i = 0; i < c; ++i) {
if(!used[i] && m[v][i] == 1) {
t = F(i);
if(t > maxn) {
maxn = t;
index = i;
}
}
}
if(index != -1) {
return DFS(index) + 1;
}
else {
return 0;
}
}
int main() {
cin >> c;
for(int i = 0; i < c; ++i) {
for(int j = 0; j < c; ++ j)
cin >> m[i][j];
}
int maxn = DFS(0) + DFS(0) + 1;
cout << maxn << endl;
}

when i was using pointers in function arguments i faced with an error

The error is this:
cannot convert int*' toint*' for argument 1' tobool permition(int*, int, int)'
Here in code i have a int board[n], and the user gives the 'n'...
i want to give my permition function this array so i had to give it by pointers because the length of it is not specified...So how can i solve this problem
Here is my code:
#include <cstdlib>
#include <iostream>
#include <cmath>
using namespace std;
bool permition(int* board[],int place,int n_){
int m=place;
while(m!=0){
m--;
if(abs(abs(board[m]-board[place])-abs(m-place))==1
&& abs(m-place)<3 && abs(board[m]-board[place]))
return false;
}
return true;
}
void printBoard(int* board[],int n){
for(int i=0;i<n;i++)
cout << board[i]<< " ";
cout << endl;
}
int main()
{
int p=0;
int n;
cout << "plz: ";
cin >> n;
int board[n];
for(int i=0;i<n;i++)
board[i]=0;
while(p<n){
while((board[p]<n) && permition(board,p,n)==false)
board[p]+=1;
if(board[p]<n)
p++;
else{
p--;
board[p]+=1;
}
if(p==n && board[0]<n-1)
//it means the first number is not max so we should
//print and continue from fist again
{
printBoard(board,n);
p=0;
board[0]+=1;
}
}
system("PAUSE");
return 0;
}
Get rid of [] in the function definition of permition:
bool permition(int* board,int place,int n_)
See if that helps!
Change
bool permition(int* board[],int place,int n_)
to
bool permition(int const board[],int place,int n_)
The current argument declaration (first above) says that board is an array of pointers to int, which it isn't.
The [] ends up as a pointer, so you can alternatively write
bool permition(int const* board,int place,int n_)
This form has the advantage that you can use const also on the pointer, while with [] you have a pointer that can be changed but that looks like an array.
The disadvantage is that the declaration no longer communicates "array" to the reader.
As others have noted, the original code passes an array of int (which is treated as an int *) to a function that's declared to take a pointer to an array of int. Here's a corrected version, with some formatting changes that I hope will be helpful.
#include <cstdlib>
#include <iostream>
#include <cmath>
using namespace std;
// Removed unused parameter n_.
bool permission(int board[], int place) {
int m = place;
// The original code could return false only if (place - m) < 3,
// so no need to test when (place - m) >= 3.
while (m-- > max(0, place - 3) {
int board_diff = abs(board[m] - board[place];
int index_diff = place - m; // Always >= 0
if (abs(board_diff - index_diff) == 1 && board_diff != 0) {
return false;
}
}
return true;
}
void printBoard(int board[], int n) {
for (int i = 0; i < n; i++) {
cout << board[i] << " ";
}
cout << endl;
}
int main() {
int p = 0;
int n;
cout << "plz: ";
cin >> n;
int board[n] = { 0 }; // Zeroes entire array.
while (p < n) {
// Never compare bool to true or false; just use !bool_var.
while ((board[p] < n) && !permission(board, p)) {
board[p]++;
}
if (board[p] < n) {
p++;
} else {
board[--p]++;
}
if (p == n && board[0] < (n - 1)) {
// The first number is not max so we should
// print and continue from first again
printBoard(board, n);
board[p = 0]++; // Assign and increment.
}
}
system("PAUSE");
return 0;
}
int board[];
is the same as
int *board;
so the solution in my guess is to write that
bool permition(int board[],int place,int n_)
void printBoard(int board[],int n)
You need to understand and to work more on pointers !

Unique sort order of array c++

How would I sort an array of integers (0,1,2,3,4,5) in a monge shuffle type order (greatest odd to least odd, then least even to greatest even) like (5,3,1,0,2,4). Im having trouble trying to solve this problem.
Ive tried so far:
void mongeShuffle(int A[], int B[], int size)
{
int i = 0; // i is the index of the arr
while(i < size)
{
if(A[i] % 2 == 1)
{
B[i] = A[i];
i++;
}
else
{
B[i] = A[i -1];
i++;
}
}
}
In c++ you can use algorithm header to use sort function and supply your custom comparator. Something like this:
#include <algorithm>
#include <iostream>
bool my_comp (int a, int b)
{
if( a%2 == 1 && b%2 == 1)
{
// Both odd
return a > b;
}
else if( a%2 == 0 && b%2 == 0)
{
// Both even
return a < b;
}
else return a%2 == 1;
}
int main()
{
int A[] = {0,1,2,3,4,5};
std::sort(A, A + 6, my_comp);
for(int i: A)
{
std::cout << i << std::endl;
}
}
You need to shuffle based on the indices being even or odd, not the values.
#include <iostream>
void mongeShuffle(int A[], int B[], int size)
{
for(int i = 0; i < size; ++i)
{
if(i % 2 == 0)
{
B[(size+i)/2] = A[i];
}
else
{
B[size/2 - i/2 - 1] = A[i];
}
}
}