I am trying to solve the following problem from ACM Timus:
http://acm.timus.ru/problem.aspx?space=1&num=1242 , but I don't how to read the input correctly. I am using two while loops. The first one terminates once a string is written in the input but the second one doesn't work after that. Here's my code:
#include <iostream>
#include <vector>
using namespace std;
struct Pair
{
void AddParent(int a)
{ parents.push_back(a); }
void AddChild(int a)
{ children.push_back(a);}
vector<int> parents;
vector<int> children;
};
vector<bool> visited;
vector<Pair> graph;
void DFS1(int n)
{
visited[n] = true;
for(int i = 0 ; i < graph[n].parents.size() ; i++)
{
int t = graph[n].parents[i];
if(!visited[t])
DFS1(t);
}
return;
}
void DFS2(int n)
{
visited[n] = true;
for(int i = 0 ; i < graph[n].children.size() ; i++)
{
int t = graph[n].children[i];
if(!visited[t])
DFS2(t);
}
return;
}
int main()
{
int n;
cin >> n;
graph.resize(n);
visited.resize(n);
int a,b,c;
vector<int> victim;
////////////////////////////////
while(cin >> a && cin >> b)
{ a--;b--;
graph[a].AddParent(b);
graph[b].AddChild(a);
}
cin.clear();
cin.ignore();
while(cin >> c)
{
victim.push_back(c);
}
////////////////////////////////
for(int i = 0 ; i < victim.size() ; i++)
if(!visited[victim[i]]){
DFS1(victim[i]);
DFS2(victim[i]);
}
bool vis = false;
for(int i = 0 ; i < n ; i++)
if(!visited[i])
{
vis = true;
cout << i + 1 << " ";
}
if(!vis)
cout << 0;
return 0;
}
Before going to the second while loop you should clear the input stream cin.
while(cin >> a && cin >> b)
{ a--;b--;
graph[a].AddParent(b);
graph[b].AddChild(a);
}
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
while(cin >> c)
{
victim.push_back(c);
}
And include the header limits
Why would we call cin.clear() and cin.ignore() after reading input?
Related
Currently I am making dynamic allocation of structs within structs in C++. So, I made a code that can be dynamically allocated that I think.
Here is the code that I made it :
#include<iostream>
using namespace std;
int cnt = 0;
struct num{
int x;
int y;
};
struct name {
char Stu[30] = { 0 };
num *number;
};
int input(int& a) {
if (cnt == 0) {
cout << "입력할 수 : ";
cin >> a;
cnt++;
return a;
}
if (cnt == 1) {
cout << "입력할 수 : ";
cin >> a;
cnt++;
}
}
void input(char *pt) {
if (cnt == 2) {
cout << "입력할 글자 : ";
cin >> pt;
cnt++;
}
}
int inputnum(int i) {
cout << "할당할 숫자를 쓰시오 : ";
cin >> i;
return i;
}
void printdata(name *pSt, int i, int j) {
cout << pSt[i].number[j].x << endl;
cout << pSt[i].number[j].y << endl;
cout << pSt[i].Stu << endl;
}
int main() {
int num1 = 0;
int num2 = 0;
num1 = inputnum(num1);
num2 = inputnum(num2);
name* student = new name[num1];
for (int i = 0; i < num1; i++) {
for (int j = 0; j < num2; j++) {
student[i].number = new num[num2];
input(student[i].number[j].x);
input(student[i].number[j].y);
input(student[i].Stu);
cnt = 0;
}
}
for (int i = 0; i < num1; i++) {
for (int j = 0; j < num2; j++) {
printdata(student, i, j);
}
}
}
But if I input more than 2 in num2, output number is weird like -842150451.
How can I do dynamic assignment to a struct inside a struct in C++?
There are several issues with your code.
First, use std::string instead of char[30]. Second, don't allocate memory unless is necessarily. There is no need for num* number. Use a std::vector.
You can put your code as follows:
struct num {
int x;
int y;
};
struct name {
std::string Stu;
std::vector<num> number;
};
-842150451 is not a weird number. It's decimal for 0xCDCDCDCD. This is a value used by Microsoft debug CRT to represent uninitialized heap memory. See here.
Concerning the input functions, why don't you write some simpler functions?
void input_x(int& x)
{
cout << "입력할 수 : ";
cin >> x;
}
void input_y(int& y)
{
cout << "입력할 수 : ";
cin >> y;
}
void input_s(char *pt)
{
cout << "입력할 글자 : ";
cin >> pt;
}
Which you can use as follows:
for (int i = 0; i < num1; i++) {
for (int j = 0; j < num2; j++) {
student[i].number = new num[num2];
input_x(student[i].number[j].x);
input_y(student[i].number[j].y);
input_s(student[i].Stu);
}
}
The input_s should use std::string, though, if you use what I suggest above:
void input_s(std::string& pt)
{
cout << "입력할 글자 : ";
cin >> pt;
}
As for name* student you can replace that with std::vector<name>:
std::vector<name> student;
for (int i = 0; i < num1; i++) {
for (int j = 0; j < num2; j++) {
name s;
s.number.resize(num2);
input(s.number[j].x);
input(s.number[j].y);
input(s.Stu);
student.push_back(s);
}
}
I dont understand why is this code giving runtime error on input of any test case (size of string is n, and then string is input). Not even the word "CHECK" (in the solve() function) gets printed.. Please help!
The problem link is : problem
#include <bits/stdc++.h>
using namespace std;
int a[1000][26];
int mov(int l, int u, int x)
{
if(l==u)
{
if(a[l][x]-a[l-1][x]==1)
return 1;
else
return 0;
}
int m=(l+u)/2;
return max(mov(l,m,x+1)+a[u][x]-a[m][x],mov(m,u,x+1)+a[m][x]-a[l-1][x]);
}
void solve()
{
int i,k,j,n;
string str;
cin >> n >> str;
cout << "CHECK";// This is not getting printed
for(i=0;i<26;i++)
a[0][i]=0;
for(i=1;i<n+1;i++)
{
for(j=0;j<26;j++)
{
a[i][j]=a[i-1][j];
if(str[i-1]==j+'a')
a[i][j]++;
}
}
k=mov(1,n,0);
cout << n-k << "\n";
}
int main()
{
int t=1;
cin >> t;
while(t--)
solve();
}
Your very first input shows how many input "pairs" will be given. In your case, you have skipped this part and gone into gathering the input "pairs". This is why "CHECK" wont get printed. To resolve this, have a cin to capture the number of input pairs, then iterate through the inputs to get the pair.
void solve()
{
int i, k, j, n;
string str;
memset(a[0], 0, sizeof(int) * 26); // Use this instead.
cin >> n;
cout << "CHECK";
for (i = 1; i < n + 1; i++)
{
cin >> j >> str;
for (j = 0; j < 26; j++)
{
a[i][j] = a[i - 1][j];
if (str[i - 1] == j + 'a')
a[i][j]++;
}
}
k = mov(1, n, 0);
cout << k << "\n";
}
Also, try not to use using namespace std;.
My code:
#include<iostream>
#include<conio.h>
using namespace std;
int main()
{
int a;
while ((cin >> a))
{
if (a == 0)
break;
char inp[401];
cin >> inp;
for (int i = 0; i < a; i += 1)
{
for (int j = i; j < 400; j += a)
{
if (inp[j] == '\0')
break;
cout << inp[j] << endl;
}
}
cout << endl;
}
getchar();
return 0;
}
Error is that I get no output when it should be printing the characters stored in inp[j].Please help resolve this problem.
Input:
5
toioynnkpheleaigshareconhtomesnlewx
Expected Output:
theresnoplacelikehomeonasnowynightx
Your question is very cryptic, just like the problem of decryption you are trying to solve. The following code produces the expected output for your given input.
#include<iostream>
#include<conio.h>
using namespace std;
int main()
{
int a;
while ((cin>>a))
{
if (a == 0)
break;
string inp;
cin >> inp;
int f = 9,s=1;
int inc = f;
for(int i = 0; i < a; i++)
{
for (int j = i; j < inp.length() ; )
{
cout << inp[j];
j += inc;
inc = inc==f?s:f;
}
f-=2;
s+=2;
inc = f;
}
cout << endl;
}
getchar();
return 0;
}
#Jason Ball this is the whole function:
std::ifstream InFile(filename);
if (!InFile)
return E_FAIL;
std::vector<Layer>Layers;
std::vector<PatternSet>Patterns;
std::vector<Mood>Moods;
Layer layer;
PatternSet ps;
Mood mood;
Theme theme;
layer.fileInfo.padding = layer.fileInfo.data = nullptr;
layer.fileInfo.len = 0;
std::string cmd;
while (true)
{
InFile >> cmd;
if (!InFile)
break;
if (cmd == "f")
{
InFile >> layer.fileInfo.filename;
}
else if (cmd == "fp")
{
int data, n; InFile >> n;
for (int a = 0; a < n; a++)
{
InFile >> data;
layer.fadePoints.push_back(data);
}
}
else if (cmd == "sp")
{
int data, n; InFile >> n;
for (int a = 0; a < n; a++)
{
InFile >> data;
layer.syncPoints.push_back(data);
}
}
else if (cmd == "v")
{
InFile >> layer.volume;
}
else if (cmd == "#layerend")
{
Layers.push_back(layer);
}
else if (cmd == "#patternset")
{
int Index;
for (int a = 0; a < 5; a++)
{
InFile >> Index;
if (Index != -1)
ps.pattern[a] = std::move(Layers[Index]);
}
Patterns.push_back(ps);
memset(ps.pattern, 0, sizeof(Layer)* 5);
}
else if (cmd == "#mood")
{
InFile >> mood.name;
int Index, n; InFile >> n;
for (int a = 0; a < n; a++)
{
InFile >> Index;
mood.data.push_back(Patterns[Index]);
}
Moods.push_back(mood);
mood.data.clear();
}
else if (cmd == "#theme")
{
InFile >> theme.name;
int Index, n; InFile >> n;
for (int a = 0; a < n; a++)
{
InFile >> Index;
theme.data.push_back(Moods[Index]);
}
m_vTheme.push_back(theme);
theme.data.clear();
}
else
{
}
}
return S_OK;
and here is a file:
#layer
f filename
fp 4 0 1998 1245 1003482
sp 3 500 1200 9500
v 0.95
#layerend
#layer
f filename2
fp 4 0 1998 1245 1003482
sp 3 500 1200 9500
v 0.75
#layerend
#patternset -1 0 -1 -1 -1
#patternset -1 1 -1 -1 -1
#mood name n 0 1
#theme name n 0
#Jason Ball here you have those structures as well:
struct node
{
union{
struct{
std::string filename;
void *padding;
};
struct{
void *data;
unsigned int len;
};
};
};
struct Theme;
struct Mood;
struct PatternSet;
struct Layer
{
node fileInfo;
std::vector<int> fadePoints;
std::vector<int> syncPoints;
float volume;
PatternSet *pUp;
};
struct PatternSet
{
union{
struct{
Layer pattern[5];
};
struct{
Layer start;
Layer main;
Layer end;
Layer rhytmic;
Layer incidental;
};
};
Mood *pUp;
};
struct Mood
{
std::vector<PatternSet> data;
std::string name;
Theme *pUp;
};
struct Theme
{
std::vector<Mood> data;
std::string name;
};
When I set breakpoints everywhere, it shows that after first if block it jumps to return line even when the file contains more than 5 000 lines.
I had the same problem a few months ago, but it somehow got to work. Any ideas what can cause this problem?
try this. Hope it helps.
{
ifstream InFile("text.txt");
if (!InFile) return 0;
string cmd;
while (InFile >> cmd)
{
cout << "\ncmd " << cmd;
if (cmd == "f")
{
string name;
if (InFile >> name) {
layer.fileInfo.filename = name;
cout << "\nfilename: " << layer.fileInfo.filename;
}
}
else if (cmd == "fp")
{
int data, n;
if (InFile >> n) {
for (int a = 0; a < n; a++)
{
if (InFile >> data) {
cout << "\nAdding " << data;
layer.fadePoints.push_back(data);
}
}
}
}
else if (cmd == "sp")
{
int data, n;
if (InFile >> n) {
for (int a = 0; a < n; a++)
{
if (InFile >> data) {
layer.syncPoints.push_back(data);
}
}
}
}
else if (cmd == "v")
{
float vol;
if (InFile >> vol) {
layer.volume = vol;
}
}
else if (cmd == "#layerend")
{
Layers.push_back(layer);
}
else if (cmd == "#patternset")
{
int Index;
for (int a = 0; a < 5; a++)
{
if (InFile >> Index) {
if (Index != -1) {
ps.pattern[a] = std::move(Layers[Index]);
}
}
}
Patterns.push_back(ps);
memset(ps.pattern, 0, sizeof(Layer)* 5);
}
else if (cmd == "#mood")
{
if (InFile >> mood.name) {
cout << "\nmood.name " << mood.name;
int Index, n;
if (InFile >> n) {
for (int a = 0; a < n; a++)
{
if (InFile >> Index) {
cout << "\nmood.data.push_back( " << Index << " )";
mood.data.push_back(Patterns[Index]);
}
}
Moods.push_back(mood);
}
}
}
else if (cmd == "#theme")
{
if (InFile >> theme.name) {
cout << "\ntheme.name " << theme.name;
int Index, n;
if (InFile >> n) {
for (int a = 0; a < n; a++)
{
if (InFile >> Index) {
cout << "\ntheme.data.push_back( " << Index << " )";
theme.data.push_back(Moods[Index]);
}
}
m_vTheme.push_back(theme);
}
}
}
else
{
//
}
}
return 1;
}
Im working on a program to take a input file, sort it and print the output. These input files will have 10 , 100, 1000 or 100000 lines which each have a number per line.
Right now, my code only works for the first 10 lines.
the main part is
int array[10];
int size;
size = sizeof array/sizeof(int);
and
if(file.is_open())
{
for(int i = 0; i < size ; ++i)
{
file >> array[i];
}
}
to read the lines of the file into the array.
How can i change this to take variable lengths of file line sizes and read it into a array.
#include<iostream>
#include<string>
#include<fstream>
#include<vector>
#include<ctime>
using namespace std;
void insertion_sort(int x[],int length)
{
int key,i;
for(int j=1;j<length;j++)
{
key=x[j];
i=j-1;
while(x[i]>key && i>=0)
{
x[i+1]=x[i];
i--;
}
x[i+1]=key;
}
}
int main()
{
int array[10];
int size;
size = sizeof array/sizeof(int);
int x;
char name[256];
string sort, order, dup;
cout << "enter a file\n";
cin >> name;
ofstream ofile;
ifstream file(name);
if(file.is_open())
{
for(int i = 0; i < size ; ++i)
{
file >> array[i];
}
}
else{
cout << "file doesnt exist";
return 1;
}
size = sizeof array/sizeof(int);
cout << "enter a sort method - type insertion_sort or merge_sort or quick_sort or counting_sort\n";
cin >> sort;
cout << "Type 'dec' for non decreasing or 'inc' for increasing order\n";
cin >> order;
cout << "Type yes or no to remove duplicates\n";
cin >> dup;
if (sort == "insertion_sort")
{
insertion_sort(array,size);
cout << "\ninsertion sort";
}
if (order == "dec" )
for(int i=0;i<size/2;i++)
swap(array[i],array[size-i-1]);
if(dup == "yes")
{
int i, j;
int NewLength = 1;
for(i=1; i< size; i++){
for(j=0; j< NewLength ; j++)
{
if(array[i] == array[j])
break;
}
if (j==NewLength )
array[NewLength++] = array[i];
}
}
cout<<endl<<"sorted "<<endl;
for(x=0;x<size;x++)
{
cout<<array[x]<<endl;
}
return 0;
}
For starters, you should be using std::vector and std::string instead of static arrays. Once you switch your code to use a vector, pulling in a file of integer data is as simple as:
std::ifstream fin("myfile.dat");
std::vector<int> myVec;
std::copy(std::istream_iterator<int>(fin), std::istream_iterator<int>(), std::back_inserter(myVec));
Which also makes the output fairly simple:
std::ofstream fout("myNewFile.dat");
std::copy(myVec.begin(), myVec.end(), std::ostream_iterator<int>(fout, " "));
Something like
std::vector<int> vec;
int x;
while (file >> x)
{
vec.push_back(x);
}
might simplify your life.