I have a string contains numbers but also contains spaces between them, i need to convert the string to int and store them in an int array .
Th following function produces a run time error
void fun(string m)
{
string temp;
int j = 0;
int h = 0;
int d;
int arr[10];
for (int i = 0; i < m.length(); i++)
{
while (m[i] != ' ')
temp[j++] = m[i];
d = atoi(temp.c_str());
arr[h++] = d;
}
for (int i = 0; i < sizeof(arr); i++)
{
cout << arr[i];
}
}
I would suggest using a stringstream for this vs. rolling your own implementation.
#include <sstream>
#include <iterator>
#include <iostream>
int main()
{
std::stringstream ss("1 2 3 4 5 6 7");
auto head = std::istream_iterator<int>(ss);
auto tail = std::istream_iterator<int>();
while(head!=tail)
{
std::cout << *head << "\n";
++head;
}
return 0;
}
if you're receiving the string in a method you can easily adapt the function above to create an empty stringstream and then pass it the string.
#include <sstream>
#include <iterator>
#include <iostream>
int main()
{
std::string astring = "1 2 3 4 5 6";
std::stringstream ss;
ss << astring;
auto head = std::istream_iterator<int>(ss);
auto tail = std::istream_iterator<int>();
while(head!=tail)
{
std::cout << *head << "\n";
++head;
}
return 0;
}
You are making several mistakes in your code.
You have not initialized temp to contain anything, but you are trying to index into its characters. Instead of temp[j++] = m[i], you need to use temp += m[i]; or temp.push_back(m[i]); or temp.append(&m[i], 1);. Or consider using an std::ostringstream to gather the characters, and then call its str() method to extract the final std::string value.
you are not incrementing i in your while loop. As soon as the for loop reaches a non-whitespace character, your while loop will end up running endlessly, continuously (and unsuccessfully) trying to append the same character to temp.
you are not doing any bounds checking to make sure your for loop does not exceed arr's max capacity of 10 numbers.
you are misusing sizeof(). sizeof(arr) returns the number of bytes that arr occupies in memory (10 * sizeof(int), which is 20 or 40 bytes, depending on your compiler's implementation of int). It is not the number of elements in the array (10). So you will exceed the bounds of the array trying to display 20/40 numbers instead of 10 numbers.
Your code is more complicated than it needs to be. You can use a std::istringstream for parsing and let it ignore whitespace for you. Use std::vector or other dynamically-sized container to receive the parsed numbers.
#include <sstream>
#include <vector>
void fun(string m)
{
std::istreamstream iss(m);
std::vector<int> vec;
int num;
vec.reserve(10); // optional
while (iss >> num) {
vec.push_back(num);
}
for (int i = 0; i < vec.size(); ++i) {
std::cout << vec[i];
}
/*
alternatively:
for (std::vector<int>::iterator iter = vec.begin(); iter != vec.end(); ++iter) {
std::cout << *iter;
}
*/
/*
alternatively (C++11 and later):
for (auto i: vec) {
std::cout << i;
}
*/
/*
alternatively (C++11 and later):
std::for_each(vec.begin(), vec.end(), [](int &n){ std::cout << n; });
*/
}
You cannot do for (int i = 0; i < sizeof(arr); i++)
The sizeof() operator gives you the size of something in bytes, which for an array of 10 ints probably amounts to 40. You need to use something like this:
#define COUNTOF(x) ((x)/sizeof((x)[0]))
for (int i = 0; i < COUNTOF(arr); i++)
The problem is in your while loop, J is 0 the first iteration through the While loop and gets incremented the first time it's called while also trying to assign it to the next letter.
Despite this issue I'd suggest using a string stream for this problem like others have said.
Here's a good reference.
Related
To find all sequences of fixed length which contain only 0 and 1 I use this code:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
void print_array(vector<string> arr) {
cout << '[';
int n = arr.size();
for (size_t i = 0; i < n; i++) {
cout << arr[i];
if (i < (n - 1)) {
cout << ", ";
}
}
cout << ']' << endl;
}
vector<string> get_variants(int n) {
vector<string> result = {"0", "1"};
vector<string> temp;
temp.reserve(2);
result.reserve(2);
for (int i=0; i < (n - 1); ++i) {
copy(result.begin(), result.end(), temp.end()); // [1]
for (int j=0; j < result.size(); ++j) {
temp[j] += "0";
result[j] += "1";
}
copy(temp.begin(),temp.end(), result.end());
temp.clear();
}
return result;
}
int main(int argc, char const *argv[]) {
int n;
cin >> n;
vector<string> maybe = get_variants(n);
print_array(maybe);
return 0;
}
But vector temp is empty, before copying in line which I marked [1] and after. So, my program's output was [0111, 1111]. What I'm doing wrong?
A more straightforward way than using std::copy is the use of .insert():
temp.insert(temp.end(), result.begin(), result.end()); //1
...
result.insert(result.end(), temp.begin(), temp.end()); // 2nd copy
You are writing to temp.end() and result.end(). These iterators represent "one past the end", and therefore writing to these iterators is Undefined Behavior.
You seem to be looking for std::back_inserter. This will create an iterator that will insert a new element to your container when it is written through.
std::copy(result.begin(), result.end(), std::back_inserter(temp));
While this answers the posted question, there remain other errors in your code leading to Undefined Behavior.
Trying to compile your program with a C++ compiler will not work, because you include #include <bits/stdc++.h>which is a non tC++ standard compliant header.
You should never include this file.
You are using typical competitive programming stuff, but including all C++ headers and not use them will eat up Compile time for no good reason.
Then, you typedef the typical competitive programming abbreviations. 2 of them, you do not use. Then there is no reason to define them.
I recommend to not do this any longer. And in C++, please use the using statement.
Then, although you want to be fast, you pass arr by value to your print function. This will copy the whole vector.
You assign/compare a lot of int with unsigned int values. This you should not do.
Additionally: Please use meaningful variable names and write comments. The more the better.
Regarding your specific bug. Both std::copy statements use end iterator as target. End is end. It is past the end of the vector. Please use std::back_inserter instead.
Regarding the algorithm. I took a while for me to realize that you basically want to create binary numbers. Nothing else. Unfortunately you translated that in a very complicated way.
Normally, you just would count from 0 to 2^n-1 and then show the data. Thats all. Becuase the numbers may be of arbitraty length, we will use manual addition of digits like in scholl on a peice of paper. Very simple.
Everthing then biols down to some lines of code.
Please see:
#include <iostream>
#include <vector>
int main() {
// Read length of binary number to create and validate input
if (int numberOfDigits{}; (std::cin >> numberOfDigits and numberOfDigits > 0)) {
// Here we will store the binary digits, so 0s or 1s
std::vector<int> digits(numberOfDigits,0);
// Som printing helper
std::cout << '[';
bool printComma{};
// We need to print 2^n possible combinations
for (int i = 0; i < (1 << numberOfDigits); ++i) {
// Print comma, if need
if (printComma) std::cout << ','; printComma = true;
// Print all digits of the binary number
for (const int d : digits) std::cout << d;
// Calculate next binary number
int carry = 0;
for (int index=numberOfDigits -1; index >=0; --index) {
const int sum = digits[index] + ((index == (numberOfDigits - 1)?1:0)) + carry;
carry = sum / 2;
digits[index] = sum % 2;
}
}
std::cout << ']';
}
}
If there should be questions, then I am happy to answer.
As part of my homework assignment, I have to split a char[] by its indices. So for example, the main function looks like:
int main()
{
char str[] = "A string to be split into given number of parts";
int split_size;
cout << "Enter the size of the part: ";
cin >> split_size;
int size = sizeof(str) / sizeof(str[0]);
SplitString(str, split_size, size);
int wait;
cin >> wait;
return 0;
}
Then using the function SplitString, the first x elements are printed, new line, then the next.
My first idea, was to use two for loops. One loops through the splits (i.e. if there are 4 splits, the range on this loop is 0 to 3), then the second loops through the split itself, iterating over the array elements.
My SplitString() function looks like this:
void SplitString(char str[], int split_size, int size) {
int parts = size / split_size;
for (int i = 0; i < parts; i++) {
for (int j = 0; j < split_size; j++) {
j = split_size * i;
cout << str[j];
}
cout << endl;
}
}
Is there an easier way to do this? I know in Python, you can use the arr[1:] to grab a range of elements from the array. Is there anything similar in C++? Is there some flaw in my logic? Is there something wrong with my code?
cout comes with a write function that takes a pointer and a size argument.
for (int i = 0; i < parts; i++) {
cout.write (str+i*split_size, split_size)
cout << endl;
}
Note that the code above does not check if the string is actually long enough. If the total size is not equal the split_size times a whole number, you will have to add an additional check.
Also, note that this:
int size = sizeof(str) / sizeof(str[0]);
can be written as:
int size = sizeof(str);
instead because the size of a char is always 1.
You can use std::string for this. Alternatively, if your compiler supports C++17, you can use std::string_view as the first argument of SplitString to avoid unnecessary copying.
#include <algorithm>
#include <iostream>
#include <string>
void SplitString(std::string s, std::size_t split_size)
{
while(!s.empty())
{
auto size = std::min(split_size, s.size());
std::cout << s.substr(0, size) << '\n';
s = s.substr(size, std::string::npos);
}
}
int main()
{
char str[] = "A string to be split into given number of parts";
int split_size = 5;
SplitString(str, split_size);
return 0;
}
Live example.
I'm trying to delete all elements of an array that match a particular case.
for example..
if(ar[i]==0)
delete all elements which are 0 in the array
print out the number of elements of the remaining array after deletion
what i tried:
if (ar[i]==0)
{
x++;
}
b=N-x;
cout<<b<<endl;
this works only if i want to delete a single element every time and i can't figure out how to delete in my required case.
Im assuming that i need to traverse the array and select All instances of the element found and delete All instances of occurrences.
Instead of incrementing the 'x' variable only once for one occurence, is it possible to increment it a certain number of times for a certain number of occurrences?
edit(someone requested that i paste all of my code):
int N;
cin>>N;
int ar[N];
int i=0;
while (i<N) {
cin>>ar[i];
i++;
}//array was created and we looped through the array, inputting each element.
int a=0;
int b=N;
cout<<b; //this is for the first case (no element is deleted)
int x=0;
i=0; //now we need to subtract every other element from the array from this selected element.
while (i<N) {
if (a>ar[i]) { //we selected the smallest element.
a=ar[i];
}
i=0;
while (i<N) {
ar[i]=ar[i]-a;
i++;
//this is applied to every single element.
}
if (ar[i]==0) //in this particular case, we need to delete the ith element. fix this step.
{
x++;
}
b=N-x;
cout<<b<<endl;
i++;
}
return 0; }
the entire question is found here:
Cut-the-sticks
You could use the std::remove function.
I was going to write out an example to go with the link, but the example form the link is pretty much verbatim what I was going to post, so here's the example from the link:
// remove algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::remove
int main () {
int myints[] = {10,20,30,30,20,10,10,20}; // 10 20 30 30 20 10 10 20
// bounds of range:
int* pbegin = myints; // ^
int* pend = myints+sizeof(myints)/sizeof(int); // ^ ^
pend = std::remove (pbegin, pend, 20); // 10 30 30 10 10 ? ? ?
// ^ ^
std::cout << "range contains:";
for (int* p=pbegin; p!=pend; ++p)
std::cout << ' ' << *p;
std::cout << '\n';
return 0;
}
Strictly speaking, the posted example code could be optimized to not need the pointers (especially if you're using any standard container types like a std::vector), and there's also the std::remove_if function which allows for additional parameters to be passed for more complex predicate logic.
To that however, you made mention of the Cut the sticks challenge, which I don't believe you actually need to make use of any remove functions (beyond normal container/array remove functionality). Instead, you could use something like the following code to 'cut' and 'remove' according to the conditions set in the challenge (i.e. cut X from stick, then remove if < 0 and print how many cuts made on each pass):
#include <iostream>
#include <vector>
int main () {
// this is just here to push some numbers on the vector (non-C++11)
int arr[] = {10,20,30,30,20,10,10,20}; // 8 entries
int arsz = sizeof(arr) / sizeof(int);
std::vector<int> vals;
for (int i = 0; i < arsz; ++i) { vals.push_back(arr[i]); }
std::vector<int>::iterator beg = vals.begin();
unsigned int cut_len = 2;
unsigned int cut = 0;
std::cout << cut_len << std::endl;
while (vals.size() > 0) {
cut = 0;
beg = vals.begin();
while (beg != vals.end()) {
*beg -= cut_len;
if (*beg <= 0) {
vals.erase(beg--);
++cut;
}
++beg;
}
std::cout << cut << std::endl;
}
return 0;
}
Hope that can help.
If you have no space bound try something like that,
lets array is A and number is number.
create a new array B
traverse full A and add element A[i] to B[j] only if A[i] != number
assign B to A
Now A have no number element and valid size is j.
Check this:
#define N 5
int main()
{
int ar[N] = {0,1,2,1,0};
int tar[N];
int keyEle = 0;
int newN = 0;
for(int i=0;i<N;i++){
if (ar[i] != keyEle) {
tar[newN] = ar[i];
newN++;
}
}
cout<<"Elements after deleteing key element 0: ";
for(int i=0;i<newN;i++){
ar[i] = tar[i];
cout << ar[i]<<"\t" ;
}
}
Unless there is a need to use ordinary int arrays, I'd suggest using either a std::vector or std::array, then using std::remove_if. See similar.
untested example (with c++11 lambda):
#include <algorithm>
#include <vector>
// ...
std::vector<int> arr;
// populate array somehow
arr.erase(
std::remove_if(arr.begin(), arr.end()
,[](int x){ return (x == 0); } )
, arr.end());
Solution to Cut the sticks problem:
#include <climits>
#include <iostream>
#include <vector>
using namespace std;
// Cuts the sticks by size of stick with minimum length.
void cut(vector<int> &arr) {
// Calculate length of smallest stick.
int min_length = INT_MAX;
for (size_t i = 0; i < arr.size(); i++)
{
if (min_length > arr[i])
min_length = arr[i];
}
// source_i: Index of stick in existing vector.
// target_i: Index of same stick in new vector.
size_t target_i = 0;
for (size_t source_i = 0; source_i < arr.size(); source_i++)
{
arr[source_i] -= min_length;
if (arr[source_i] > 0)
arr[target_i++] = arr[source_i];
}
// Remove superfluous elements from the vector.
arr.resize(target_i);
}
int main() {
// Read the input.
int n;
cin >> n;
vector<int> arr(n);
for (int arr_i = 0; arr_i < n; arr_i++) {
cin >> arr[arr_i];
}
// Loop until vector is non-empty.
do {
cout << arr.size() << endl;
cut(arr);
} while (!arr.empty());
return 0;
}
With a single loop:
if(condition)
{
for(loop through array)
{
if(array[i] == 0)
{
array[i] = array[i+1]; // Check if array[i+1] is not 0
print (array[i]);
}
else
{
print (array[i]);
}
}
}
So I wanted to clean the rust off my C++ skills and thought I'd start with something fairly simple. An equilibrium point in a vector A of size N is a point K, such that: A[0] + A[1] + ... + A[K−1] = A[K+1] + ... + A[N−2] + A[N−1]. The rationale behind the function algorithm is simple: Check each consecutive element of the vector and compare the sum of the elements before said element with the sum of the elements after it and if they are equal, output the index of that element. While it sounds simple (and I imagine that it is) it turned out to be harder to implement in reality. Here's what the code looks like:
#include <iostream>
#include <vector>
using std::cin;
using std::cout;
using std::endl;
void EquilibriumPoint(std::vector<int> &A);
void VectorPrint(std::vector<int> &V);
void main()
{
int input;
std::vector<int> Vect1;
cout << "Input the vector elements" << endl;
while (cin >> input)
Vect1.push_back(input);
VectorPrint(Vect1);
EquilibriumPoint(Vect1);
}
void EquilibriumPoint(std::vector<int> &A)
{
for (int it = 0; it != A.size(); ++it)
{
int lowersum = 0;
int uppersum = 0;
for (int beg = 0; beg != it; ++beg) lowersum += A[beg];
for (int end = it + 1; end != A.size(); ++end) uppersum += A[end];
if (uppersum == lowersum) cout << it;
}
}
void VectorPrint(std::vector<int> &V)
{
for (int i = 0; i != V.size(); ++i)
cout << V[i] << endl;
}
As you can see I threw in a print function also for good measure. The problem is that the program doesn't seem to execute the EquilibriumPoint function. There must be a problem with the logic of the implementation but I can't find it. Do you guys have any suggestions?
cin >> input
always returns true for you - so IMHO you have an endless loop. You need to stop collecting elements at some point, for instance
int input = 1
while (input)
{
cin >> input;
Vect1.push_back(input);
}
Will accept all elements that are not zero, when zero arrives, it will end the vector and run your function.
Or you can first input the number of elements (if you want to include zeros), example:
int count;
cin >> count
for (int i = 0; i < count; ++i)
{
cin >> input;
Vect1.push_back(input);
}
I didn't check the rest of the code, though. One problem at a time.
This program reads strings of numbers from a txt file, converts them to integers, stores them in a vector, and then tries to output them in an organized fashion like so....
If txt file says:
7 5 5 7 3 117 5
The program outputs:
3
5 3
7 2
117
so if the number occurs more than once it outputs how many times that happens. Here is the code so far.
#include "std_lib_facilities.h"
int str_to_int(string& s)
{
stringstream ss(s);
int num;
ss >> num;
return num;
}
int main()
{
cout << "Enter file name.\n";
string file;
cin >> file;
ifstream f(file.c_str(), ios::in);
string num;
vector<int> numbers;
while(f>>num)
{
int number = str_to_int(num);
numbers.push_back(number);
}
sort(numbers.begin(), numbers.end());
for(int i = 0; i < numbers.size(); ++i)
{
if(i = 0 && numbers[i]!= numbers[i+1]) cout << numbers[i] << endl;
if(i!=0 && numbers[i]!= numbers[i-1])
{
cout << numbers[i] << '\t' << counter << endl;
counter = 0;
}
else ++counter;
}
}
Edit: Program is getting stuck. Looking for an infinite loop right now.
You could use a map of numbers to counters:
typedef map<int,unsigned int> CounterMap;
CounterMap counts;
for (int i = 0; i < numbers.size(); ++i)
{
CounterMap::iterator it(counts.find(numbers[i]));
if (it != counts.end()){
it->second++;
} else {
counts[numbers[i]] = 1;
}
}
... then iterate over the map to print results.
EDIT:
As suggested by lazypython: if you have the TR1 extensions [wikipedia.org] available, unordered_map should have better performance...
typedef std::tr1::unordered_map<int,unsigned int> CounterMap;
CounterMap counts;
for (int i = 0; i < numbers.size(); ++i)
{
CounterMap::iterator it(counts.find(numbers[i]));
if (it != counts.end()){
it->second++;
} else {
counts[numbers[i]] = 1;
}
}
How about using a map, where the key is the number you're tracking and the value is the number of occurrences?
If you must use a vector, you've already got it sorted. So just keep track of the number you previously saw. If it is the same as the current number, increment the counter. Every time the number changes: print out the current number and the count, reset the count, set the last_seen number to the new number.
Using a map is the practical solution. What you should do is to solve this problem :)
This is called frequency counter. So, you have a sorted vector and all what you have to do is to count successive equal numbers. In other words, you have to check each number with its successor.
for(size_t i = 0; i < numbers.size(); i++)
{
size_t count = 1;
size_t limit = numbers.size() - 1;
while(i < limit && numbers[i] == numbers[i+1])
{
count++;
i++;
}
std::cout << numbers[i] << "\t" << count << std::endl;
}
This program reads strings of numbers
from a txt file, converts them to
integers, stores them in a vector, and
then tries to output them in an
organized fashion like so....(emphasis added)
What is the point of this storage step? If you are reading the numbers from a file, then you already have them in order, ready to be processed (counted) one at time, as you encounter them.
However, I would need a way for it to know when it sees a new number.
I advise you to have a look at std::set or std::map. I expect either of these containers would do what you're looking for.
Std::count() fits the bill nicely.
std::vector<int>::const_iterator cur = numbers.begin();
std::vector<int>::const_iterator last = numbers.end();
while (cur != last) {
unsigned cnt = std::count(cur, last, *cur);
std::cout << *cur;
if (cnt != 1) {
std::cout << " " << c;
}
std::cout << std::endl;
int saved = *cur;
while (*cur == saved) {
++cur;
}
}
Of course there are a bunch of other algorithms out there that will do the same job. Play with things like std::equal_range() in conjunction with std::distance() will do the job just as nicely.
That was fun:
#include <map>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <iterator>
struct IncrementMap
{
IncrementMap(std::map<int,int>& m): m_map(m) {}
void operator()(int val) const
{
++m_map[val];
}
std::map<int,int>& m_map;
};
struct SpecialPrint
{
SpecialPrint(std::ostream& s): m_str(s) {}
void operator()(std::map<int,int>::value_type const& value) const
{
m_str << value.first;
if (value.second != 1)
{
m_str << "\t" << value.second;
}
m_str << "\n";
}
std::ostream& m_str;
};
int main()
{
std::fstream x("Plop");
std::map<int,int> data;
std::for_each( std::istream_iterator<int>(x),
std::istream_iterator<int>(),
IncrementMap(data)
);
std::for_each( data.begin(),
data.end(),
SpecialPrint(std::cout)
);
}