Correct method of implementing a recursive function in C? - recursion

I am trying to implement a recursive function into a piece of code. I have tried multiple methods but I can't quite get it right. I was wondering if there was anything I might have overlooked or if I didn't do it correctly at all.
For reference, the question I am trying to answer is the Waterloo CCC 2013 J3
#include <stdio.h>
int year, counter = 0, tempNum;
int isDistinct (int num) {
tempNum = num;
int number[10] = { 0 };
while (tempNum > 0) {
if (number[tempNum % 10] == 1) {num++; isDistinct(num);}
else { number[tempNum % 10] = 1; tempNum /= 10; }
}
return num;
}
int main() {
scanf("%d", &year);
printf("%d", isDistinct(year+1));
}

Related

Why am I getting a run-time error on school server but not on big servers like HackerEarth or HackerRank for this minimum spanning tree code?

I got a homework where I needed to wright a program to find MST of a graph. I tried running it on the school server but I get a run-time error. On big servers like HackerEarth or HackerRank, however, I got correct answers on all test cases. The boundary for the number of edges and vertices is 100000 and for the weight of an edge 10000. Vertices are labeled from 0 to n.
Here is my code:
#include <stdio.h>
#include <algorithm>
using namespace std;
class Edge
{
public:
int x, y;
long long w;
bool operator<(const Edge& next) const;
};
bool Edge::operator<(const Edge& next) const
{
return this->w < next.w;
}
class DisjointSet
{
public:
int parent, rank;
};
DisjointSet set[100100];
Edge edges[100100];
int findWithPathCompression(int x)
{
if(set[x].parent != x)
set[x].parent = findWithPathCompression(set[x].parent);
return set[x].parent;
}
bool unionByRank(int x1, int y1)
{
int x = findWithPathCompression(x1);
int y = findWithPathCompression(y1);
if(x == y)
return false;
if(set[x].rank > set[y].rank)
set[y].parent = x;
else if(set[y].rank > set[x].rank)
set[x].parent = y;
else
{
set[y].parent = x;
set[x].rank++;
}
return true;
}
int main()
{
int n, m, e = 0, c = 0;
long long r = 0;
scanf("%d %d",&n,&m);
for(int i = 0; i <= n; i++)
{
set[i].parent = i;
set[i].rank = 1;
}
for(int i = 0; i < m; i++)
{
scanf("%d %d %lld",&edges[i].x,&edges[i].y,&edges[i].w);
edges[i].x;
edges[i].y;
}
sort(edges,edges + m);
while(e != n - 1)
{
if(unionByRank(edges[c].x,edges[c].y))
{
r += edges[c].w;
e++;
}
c++;
}
printf("%lld\n",r);
}

is String or is Number function

I'm actually working on a personal "Excel" for school.
When the value of my cell is a number (int), I want to add it in my listNumber (QList int). When the value of my cell is a String, I want to add it my listString.
These two lists then allow me to sort.
The problem is here :
QString test = text(i, j);
test.toInt(&ok);
if (ok == true) {
listNumber.append(test.toInt());
qSort(listNumber.begin(), listNumber.end());
}
ERROR ASSERT failure in QList<T>::at: "index out of range" .
I think it's because it wants to "insert" a string in a list of integer.
Here my function "sort"
QList<QString> listString;
QList<int> listNumber;
bool ok;
QTableWidgetSelectionRange range = selectedRange();
for (int j = range.leftColumn(); j <= range.rightColumn(); ++j) {
for (int i = range.topRow(); i <= range.bottomRow(); ++i) {
QString test = text(i, j);
test.toInt(&ok);
if (ok == true) {
listNumber.append(test.toInt());
qSort(listNumber.begin(), listNumber.end());
}
}
}
if (listNumber.count() == 0) {
QMessageBox test;
test.setText("liste vide");
test.exec();
}
else {
int x = 0;
for (int j = range.leftColumn(); j <= range.rightColumn(); ++j) {
for (int i = range.topRow(); i <= range.bottomRow(); ++i) {
Spreadsheet::setFormula(i, j, QString::number(listNumber.at(x)));
x++;
}
}
}
Thank you a lot for your help.
First of all, qSort in Qt is deprecated and it is recommended not to use it:
QT_DEPRECATED_X("Use std::sort") inline void qSort(...
You can use std::sort instead:
#include <algorithm>
//...
std::sort(listNumber.begin(), listNumber.end(), std::less<int>());
//or simply:
std::sort(listNumber.begin(), listNumber.end()); // using default comparison (operator <)
(But also you can simply call deprecated qSort:)
qSort(listNumber);

BFS "Digit Jump" solution working fine on machine, get TLE on online judge

This code is for problem DIGJUMP.
It gives me correct output for all inputs i have tried (i have tried a lot of them). But the problem is that it is getting TLE while submitting it on codechef. I checked the editorial and the same solution (concept-wise) gets accepted, so it means algorithmic approach is correct. I must have something wrong in the implementation.
I tried it for a long time, but could not figure out what is wrong.
#include <string.h>
#include <vector>
#include <queue>
#include <stdio.h>
using namespace std;
class Node
{
public:
int idx, steps;
};
int main()
{
char str[100001];
scanf("%s", str);
int len = strlen(str);
vector<int> adj[10];
for(int i = 0; i < len; i++)
adj[str[i] - '0'].push_back(i);
int idx, chi, size, steps;
Node tmpn;
tmpn.idx = 0;
tmpn.steps = 0;
queue<Node> que;
que.push(tmpn);
bool * visited = new bool[len];
for(int i = 0; i < len; i++)
visited[i] = false;
while(!que.empty())
{
tmpn = que.front();
que.pop();
idx = tmpn.idx;
steps = tmpn.steps;
chi = str[idx] - '0';
if(visited[idx])
continue;
visited[idx] = true;
if(idx == len - 1)
{
printf("%d\n", tmpn.steps);
return 0;
}
if(visited[idx + 1] == false)
{
tmpn.idx = idx + 1;
tmpn.steps = steps + 1;
que.push(tmpn);
}
if(idx > 0 && visited[idx - 1] == false)
{
tmpn.idx = idx - 1;
tmpn.steps = steps + 1;
que.push(tmpn);
}
size = adj[chi].size();
for(int j = 0; j < size; j++)
{
if(visited[adj[chi][j]] == false)
{
tmpn.idx = adj[chi][j];
tmpn.steps = steps + 1;
que.push(tmpn);
}
}
}
return 0;
}
This solution won't finish in acceptable time for the problem. Remember that BFS is O(E). In a string with O(n) digits of some kind there are O(n^2) edges between those digits. For N=10^5 O(N^2) is too much.
This will need some optimizations like if we came to current node from a similar node, we wont skip further to similar nodes.

Facing incorrect output while linking programs

I am having a trouble in calling the user defined functions in the main program, using unix. the program is executing only for the number generation in the main program. but when i call the predefined function . the output retrieved is incorrect. Can someone please correct me where i have done it wrong
My main program states as
#include <stdio.h>
#include <stdlib.h>
void sort1(int []);
int main(void) {
int array[100];
int i , j;
printf("ten random numbers in [1,1000]\n");
for (i = 1; i <= 10; i++)
{
generate random numbers
}
printf("The list of Hundred random numbers are \n");
for (j = 1; j <= 10; j++ )
{
//to print the random numbers
}
sort1(array);
return 0;
}
//this is my user defined function: sort1.c
include <stdio.h>
int sort1(int a[])
{
int array[100], i, d, swap, e=10;
// algortithm
}
}
printf("Sorted list in ascending order:\n");
for ( i= 0 ; i< e ; i++ )
printf("%d\n", array[i]);
}
I get the output as
ten random numbers in [1,1000]
The list of Hundred random numbers are
--This gives correct output
Sorted list in ascending order:
1
-1442229816
0
-1444472964
#include <stdio.h>
#include <stdlib.h>
void sort1(int []);
int main(void) {
int array[100];
int i;
printf("ten random numbers in [1,1000]\n");
for (i = 1; i <= 10; i++)
{
array[i] = rand()%1000 + 1;
}
printf("The list of Hundred random numbers are \n");
for (i = 1; i <= 10; i++ )
{
printf("Element[%d] = %d\n", i, array[i] );
}
//Up to here it's ok but you have set the values in the positions 1-10 of the array so keep consistent with it
sort1(array);
printf("Sorted list in ascending order:\n");
for ( i= 1 ; i<= 10 ; i++ )
printf("%d\n", array[i]);
return 0;
}
void sort1(int a[])
{
int i,swap,sorted=0;
while(sorted==0){ //flag to know if array is sorted 0 means not sorted.
sorted=1; // we set the flag to sorted at start of sweep
for (i= 1 ; i<= (10-1); i++) //sweep through array
{
if (a[i] > a[i+1]) //check if sorted
{
swap = a[i];
a[i] = a[i+1];
a[i+1] = swap;
sorted=0; //if not sorted set flag to 0 and swap
}
}
}
}
Main problems in your code:
1) array[100] is not initialized in sort1 function.
2) I do not understand your sorting algorithm but in any case you are checking for values of a[0] which are not initialized so take care of the array positions you use each time and be consistent with it.
3) function prototype does not match

When using scanf/cin, program works fine in debug mode but gives runtime error

I'm trying to take to the following input:
1
4
47 2 4 43577
The part of my code that deals with this is:
for (scanf("%d", &t); t --; )
{
int count = 0;
scanf("%d",&n);
for (int i = 0, x; i < n; ++ i)
{
scanf("%d",&x);
str = to_string(x);
f4[i] = get_count(str,'4');
f7[i] = get_count(str,'7');
}
However, with this I get a runtime error, which shows an access violation in the file free.c.
But, when I try to debug it, it runs well in the debug mode and gives the correct answer.
Also, when I output the variable x right after I input it, the program works well in runtime as well. This is shown in the following code, which runs fine in runtime as well:
for (scanf("%d", &t); t --; )
{
int count = 0;
scanf("%d",&n);
for (int i = 0, x; i < n; ++ i)
{
scanf("%d",&x);
cout<<"A"<<i<<" is "<<x<<'\n';
str = to_string(x);
f4[i] = get_count(str,'4');
f7[i] = get_count(str,'7');
}
Any idea why this may be happening?
Some of the stackoverflow users are saying that the code runs fine. I'm using VS 2012. Can this be something that is compiler specific?
The complete code:
#include<iostream>
#include<conio.h>
#include<string>
#include<math.h>
using namespace std;
int get_count(string s, char x)
{
int count = 0;
int l = s.length();
for(int i = 0; i < l;i++)
{
if (s[i] == x)
count++;
}
return count;
}
void main()
{
int * f4 = new int;
int * f7 = new int;
string * back = new string;
int n = 0;
int t = 0;
string str;
for (scanf("%d", &t); t --; )
{
int count = 0;
scanf("%d",&n);
for (int i = 0, x; i < n; ++ i)
{
scanf("%d",&x);
str = to_string(x);
f4[i] = get_count(str,'4');
f7[i] = get_count(str,'7');
}
for(int i = 0;i < n;i++)
{
for(int j = i; j < n;j++)
{
int c4 = 0;
int c7 = 0;
for(int k = i; k <= j;k++)
{
c4 += f4[k];
c7 += f7[k];
}
double value = pow((double)c4,(double)c7);
if(value <= (double)(j - i + 1)&&(c4!=2)&&(c7!=2))
{
count++;
//cout<<"yes"<<'\t';
}
}
}
cout<<"Ans: "<<count<<'\n';
}
//getch();
}
There are no other variable assignments apart from those in this code.
The exact error that I get with runtime is:
Unhandled exception at 0x7794E3BE (ntdll.dll) in Practice1.exe: 0xC0000005: Access violation reading location 0x38389246.
You did not include the "get_count" function. I think it has something to do with that function. I rewrote that function to return some number and I don't get that error. Try to assert that you are not attempting to use a null pointer in that function.
Works fine on my machine:
Here's what I changed
for (int i = 0, x; i < n; ++ i)
{
scanf("%d",&x);
stringstream ss;
ss << x;
str = ss.str();
f4[i] = get_count(str,'4');
f7[i] = get_count(str,'7');
}
Output:
1
4
47 2 4 43577
Ans: 5

Resources