Array value changes unintentionally - c++

At first line, get inputs n (the numbers of nodes), m (the numbers of edges), start (the start node Number) and get the undirected m edges/
In the end, I want to print out the dfs result. However, when I used Node*, it changes. I don't intend to change.
class Node {
private:
int n;
Node* next = 0;
public:
Node(int _n) {
n = _n;
}
Node() {};
Node* getNext() {
return next;
}
void setNext(Node* ptr) {
next = ptr;
}
};
Below code are the main problem.
Node* arr = new Node[n + 1];// use 1 to n
for (int i = 1; i <= m; i++) {
int num1 = 0, num2 = 0;
cin >> num1 >> num2;
if (!arr[num1].getNext())
arr[num1].setNext(&Node(num2));
else {
Node* tptr = arr[num1].getNext();
while (tptr->getNext()) tptr = tptr->getNext();
tptr->setNext(&Node(num2));
}
}
I tried to save the adjacent Nodes(to Node 'i') in the arr[i].
Sample code is:
4 5 1
1 2
1 3
1 4
The result structure I expected was arr[1] -> 2 -> 3 -> 4, but the real outcome was arr[1]-> 2 -> 4 -> 4.
I don't understand why the value changes.

Related

Maximum cost path in an Undirected Graph such that no edge is visited twice

I have a graph where each node has a numeric value. Starting from a node of my choice, I have to find the path where the sum of the node values is the heaviest. However I can only cross the same bridge once BUT it is possible to pass several times on the same node.
For example if I have a undirected graph like this:
EDGES
0 1
0 2
0 3
1 2
1 4
and each node have a weight like this:
Node weight
0 -> 4
1 -> 3
2 -> 7
3 -> 2
4 -> 9
If I start from the source "1", the path's output should be like this
1->2->0->1->4 with total weight of 23.
I'm trying to solve this problem with DFS in this way:
int dfs(vector<vector<int> >& g, int* cost, int u, int pre)
{
vis[u] = true;
dp[u] = cost[u];
bool check = 1;
int cur = cost[u];
for (auto& x : g[u]) {
if (vis[x] && x != pre) {
check = 0;
} else if (!vis[x]) {
check &= dfs(g, cost, x, u);
cur = max(cur, cost[u] + dp[x]);
}
}
dp[u] = cur;
if (!check) {
canTake += cost[u];
} else {
best = max(best, dp[u]);
}
return check;
}
int FindMaxCost(vector<vector<int> >& g,int* cost, int source)
{
dfs(g, cost, source, -1);
cout << canTake + best;
}
With this I can find the right total weight but I don't know how
to save the right path.
I'm trying to take the path picking u-node in this code:
if (!check) {
canTake += cost[u];
// taking the u-node
} else {
best = max(best, dp[u]);
// taking here the last node in global variable
}
but the path is not correct.

My output have an extra 0 in it, why is that

So I'm doing practice on leetcode and this is the question:
You are given two non-empty linked lists representing two non-negative
integers. The digits are stored in reverse order and each of their nodes
contain a single digit. Add the two numbers and return it as a linked list.
You may assume the two numbers do not contain any leading zero, except the
number 0 itself.
Example:
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
Explanation: 342 + 465 = 807.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
And this is my solution:
class Solution {
public:
ListNode *addTwoNumbers(ListNode *l1, ListNode *l2) {
vector<int> V1;
vector<int> V2;
int sum1 = 0;
int sum2 = 0;
ListNode *result = new ListNode(0);
auto l0 = result;
while(l1) {
V1.push_back(l1->val);
l1=l1->next;
}
for (auto it1 = V1.rbegin(); it1 != V1.rend(); it1++) {
sum1 = sum1 * 10 + (*it1);
}
while(l2) {
V2.push_back(l2->val);
l2=l2->next;
}
for (auto it2 = V2.rbegin(); it2 != V2.rend(); it2++) {
sum2 = sum2 * 10 + (*it2);
}
int sum3 = sum1 + sum2;
while (sum3 !=0) {
int extract = sum3 % 10;
l0->next = new ListNode(extract);
sum3 /= 10;
l0=l0->next;
}
return result;
}
};
And when I ran it, there is always and extra 0 in my output, for example:
Your input
[7,2,7] [2,4,2]
Your answer
[0,9,6,9]
Expected answer
[9,6,9]
I know there is a smarter way to solve this question, but I want to try to solve it in my way first
Its because you are creating the first node with 0. You have two solutions for that:
Skip the first element at the end of the function (workaround):
ListNode* aux = result;
result = result->next;
delete aux;
return result;
Not initialize the listnode to zero, use a nullpointer instead:
s
ListNode *result = nullptr;
// More code...
while (sum3 !=0) {
int extract = sum3 % 10;
if (l0 == nullptr) {
result = new ListNode(extract);
l0 = result;
}
else
l0->next = new ListNode(extract);
sum3 /= 10;
l0=l0->next;
}
Ofc, there are better solutions. You could do the sum directly, without using extra vectors/memory.
You are getting an extra zero because you are doing remainder and division operation 1 time extra than required. You have to modify the condition under last while loop.
while (sum3 > 9) {
int extract = sum3 % 10;
l0->next = new ListNode(extract);
sum3 /= 10;
l0=l0->next;
}

Printing the second half of a linked list in reverse order

I want to print the elements of a linked list, first in their order and then, once I reach the middle, in reverse order (from the last one backwards). For example:
If the elements are: 1 2 3 4 5 6
It should print: 1 2 3 6 5 4
But it's printing: 1 2 3 5 4
Why isn't it printing the last element? How can this be solved?
void reverse()
{
int c=1;
node *current,*prev,*temp;
current=head;
prev=NULL;
std::stack<int>s;
while(current->next!=NULL)
{
c++;
s.push(current->data);
current=current->next;
}
int mid=0;
if((c%2)==0)
{
mid=c/2;
}
else
{
mid=(c+1)/2;
}
current=head;
for(int i=0;i<mid;i++)
{
cout<<current->data<<"\t";
current=current->next;
}
for(int i=mid;i>1;i--)
{
std::cout<<s.top()<<"\t";
s.pop();
}
std::cout << '\n';
}
Let's assume that the list contains only one element. In this case this loop
while(current->next!=NULL)
{
c++;
s.push(current->data);
current=current->next;
}
will be executed never and as result the stack will be empty. Moreover the function initially has undefined behavior when the list in turn is empty and hence head is equal to NULL and you may not access current->next data member.
Well now let's assume that the list contains exactly two elements. The loop will be executed only once and the variable c gets value 2. The calculated value of the variable mid will be equal to 1.
So this loop
for(int i=0;i<mid;i++)
{
cout<<current->data<<"\t";
current=current->next;
}
executes only one iteration and the first element is outputted.
However the next loop
for(int i=mid;i>1;i--)
{
std::cout<<s.top()<<"\t";
s.pop();
}
will; be executed never because its condition i > 1 yields false because mid is equal to 1.
So the program has two wrong loops that should be rewritten.
Below is a demonstrative program that shows how the function can be implemented.
#include <iostream>
#include <stack>
struct node
{
int data;
node *next;
} *head = nullptr;
void append( int data )
{
node **current = &head;
while ( *current ) current = &( *current )->next;
*current = new node { data, nullptr };
}
void clear()
{
while ( head )
{
node *tmp = head;
head = head->next;
delete tmp;
}
}
void reverse()
{
std::stack<int> s;
for ( node *current = head; current; current = current->next )
{
s.push( current->data );
}
std::stack<int>::size_type middle = ( s.size() + 1 ) / 2;
std::stack<int>::size_type i = 0;
for ( node *current = head; i < middle; i++ )
{
std::cout << current->data << '\t';
current = current->next;
}
for ( i = s.size() - i; i != 0; i-- )
{
std::cout << s.top() << '\t';
s.pop();
}
std::cout << std::endl;
}
int main()
{
const int N = 10;
for ( int i = 0; i < N; i++ )
{
for ( int j = 0; j <= i; j++ ) append( j );
reverse();
clear();
std::cout << std::endl;
}
return 0;
}
The program output is
0
0 1
0 1 2
0 1 3 2
0 1 2 4 3
0 1 2 5 4 3
0 1 2 3 6 5 4
0 1 2 3 7 6 5 4
0 1 2 3 4 8 7 6 5
0 1 2 3 4 9 8 7 6 5
Working code here:
http://ideone.com/bbzsSy
2 issues:
while(current->next!=NULL) should be: while(current!=NULL)
This way you be sure that you can dereferencing the pointer, plus you also push the last node.
for(int i=0;i<mid;i++) should be: for(int i=0;i<lastFordward;i++)
Where lastFordward=(c%2)?mid-1:mid;
This way avoid to print the mid position twice when c is even.
In your while loop you are checking if current->next is null you need to check if current is null.
while(current)
{
c++;
s.push(current->data);
current=current->next;
}
You weren't adding the last number into the stack
This method can work ... declare a function to get the size of the linkList
public int size()
{
int counter = 0;
node *nodePtr = head;
while (nodePtr)
{
if (nodePtr->next != null)
{
counter++;
}
}
return counter;
}
then if size returned is an even number ...
int c = size()/2;
else ...
int c = (size()+1)/2;
then initialize and array and print them in reverse .... try it out might work :)
In a typical linked list implementation the last node points to nothing (typically nullptr). Your stop condition for adding the existing elements (current->next!=nullptr) to the stack therefore doesn't include the last element.
Iterating over current would be a better approach as that would stop one after the last node.
Also note that this will have an impact on your mid-point calculation as it is off by one from the start.
It's not quite going to compile, but this is somewhat fewer lines:
// assert myList is sorted before called
// if it's not, add
// std::sort(myList.begin(), myList.end());
// as the first line of the function
void reverseLatterHalf(std::vector& myList) {
auto it = myList.begin() + myList.size() / 2;
std::reverse(it, myList.end());
}

How do I do the following recursive function?

Ok, so I have a regular Node list, with members info and next.
I need to use a function, recursively, to calculate the average, and then compare if each node is bigger than the average or not.
int Acount(NodeType* Node, int sum, int& avg){
if (Node == NULL){//last call
avg = sum / avg;
return 0;
}
else {
return (Acount(Node->next, sum + Node->info, ++avg) + (Node->info > avg ? 1 : 0));
}
}
Which is quite simple. Problem is the value returned is always 0.
The problem appears to be with
(Node->info > avg ? 1 : 0));
I've done the tests and when I do the following:
return (Acount(Node->next, sum + Node->info, ++avg) + Node->info;
or
return (Acount(Node->next, sum + Node->info, ++avg) + avg;
Results meet expectations. As in, I'm getting the sum of the Node->info in the first case, and I'm getting average*number of nodes in the second case.
Point of this, I've proved that the function is working perfectly.
Yet when it comes to
(Node->info > avg ? 1 : 0));
Appears to be problematic, which is quite peculiar. if I place for example:
(Node->info == 5 ? 1 : 0));
And there is only one 5 in the nodes, then the function returns 1. So everything is working as intended, yet I keep getting a 0.
The following are the main functions and additional functions for the Node.
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
struct NodeType{
int info;
NodeType *next;
};
//pre: first node passed is not NULL
int Acount(NodeType* Node, int sum, int& avg){
if (Node == NULL){//last call
avg = sum / avg;
return 0;
}
else {
return (Acount(Node->next, sum + Node->info, ++avg) + (Node->info > avg ? 1 : 0));
}
}
void fill(NodeType*& Node){
NodeType *temp;
Node = new NodeType;
Node->info = 0;
Node->next = NULL;
temp = Node;
for (int i = 1; i < 10; i++){
temp->next = new NodeType;
temp = temp->next;
temp->info = i;
temp->next = NULL;
}
}
void print(NodeType* Node){
NodeType *temp = Node;
while (temp != NULL){
cout << temp->info << " ";
temp = temp->next;
}
cout << endl;
}
void Delete(NodeType* Node){
NodeType *temp;
while (Node != NULL){
temp = Node;
Node = Node->next;
delete temp;
}
}
void main(){
int sum = 0, avg = 0;
NodeType *Node;
fill(Node);
print(Node);
cout << Acount(Node, sum, avg) << endl;
Delete(Node);
}
In C++ there is no concept of left-to-right (or right-to-left) evaluation order of expressions. Operator priorities will control associativity, but in the case of f1() + f2() there is no guarantee that f1() is invoked before f2() (and viceversa). It may depend on the compiler or other.
My suggestion is to split the expression into 2 distinct statements as follows:
int tmp = Acount(Node->next, sum + Node->info, ++avg);
return tmp + (Node->info > avg ? 1 : 0);
I am not sure if your code has defined behaviour. But, this line
return (Acount(Node->next, sum + Node->info, ++avg) + (Node->info > avg ? 1 : 0));
depends on if the left summand or the right summand is calculated first.
If it is the left one, then Acount goes down the recursion an incrementing avg until avg equals the number of elements in the list (here 10 when starting from zero called by the main routine). Note, that avg is passed by reference. Thus, when the recursion goes back up, this term in the right summand
Node->info > avg
will never be true because Node->info is set in the fill routine to values smaller then the number of elements.
I don't think your method will work.
In this statement:
return (Acount(Node->next, sum + Node->info, ++avg) + (Node->info > avg ? 1 : 0))
You don't know when the second term has be evaluated. It's not defined in C++.

I don't quite understand this algorithm on queue

Here's the queue using array implementation in Robert Sedgewick's book:
class QUEUE {
private:
int* q;
int N;
int head;
int tail;
public:
QUEUE(int maxN) {
q = new int[maxN + 1];
N = maxN + 1; head = N; tail = 0;
}
int empty() const {
return head % N == tail;
}
void put(int item) {
q[tail++] = item; tail = tail % N;
}
int get() {
head = head % N; return q[head++];
}
};
My concern is about the get() method.
Consider the size to be 10;
According to the code, initially, the index of head = 11 and index of tail = 0.
Now, add an element, say 1. So, 1 is placed in the index position 0 and the tail position is incremented to 1.
Now add another say 5. 5 is at index pos 1 and the tail now is index 2.
Now use the get() function, which does: return q[head++]; which is to return the element at head and then increment the head but BOOOOOM!!!!! The head is index no 11 as we have just seen and it has no value stored in it and this must be a huge error. But, this code is correct as it's Robert Sedgewick and we are the one's mistaken. What's going on guys? :(
If you create a queue with size 10 then head equals 10. In get we use
head = head % N;
head = 10 % 10
head = 0
So head is 0 and then we increment it to 1.
You are missing out the `
head = head % n; // this mean head is now the remainder of the division
// between head and N`
It means head is no longer 10;
head = 11 % 11
which is 0 as the remainder of this division is zero.
Therefore, head = 0;
Then when you return q[head++], you are returning q[0] and then you are setting head to 1.