C++ string array about nums - c++

Say the strings is "Asah1234&^%736hsi)(91",
than storage 1234,736,91 in three arrays
In general,i want to put each continuous nums in each array.
Queations: how many arrays i will need,what's the size of each group of numbers,how to make the loop.
I want to write a fuction to do it.
#include<iostream>
using namespace std;
void splitString(string str)
{
string num;
for (int i = 0; i < str.length(); i++)
{
if (isdigit(str[i]))
num.push_back(str[i]);
}
cout << num << endl;
}
int countnum( string str)
{
string num;
int sum = 0;
for (int i = 0; i < str.length(); i++)
{
if (isdigit(str[i]))
sum++;
}
cout << sum << endl;
return 0;
}
int main()
{
const int MAXLEN = 100;
char str[MAXLEN];
printf("please enter strings:");
scanf_s("%s", str, MAXLEN);
splitString(str);
countnum( str);
return 0;
}

Maybe I have a misunderstanding here. Then please comment and I will delete the answer.
This is a standard task and will be solved with a regex. It is just the definition of a variable and initialzing this variable with its range constructor. So, a one-liner.
There is no further statement needed.
Please see:
#include <iostream>
#include <string>
#include <regex>
#include <vector>
std::regex re{ R"(\d+)" };
int main() {
// The input string with test data
std::string test{"Asah123&^%736hsi)(918"};
// Define a variable numbers and use the range constructor to put all data in it
std::vector numbers(std::sregex_token_iterator(test.begin(), test.end(), re), {});
// Show the result on the screen
for (const auto& n : numbers) std::cout << n << "\n";
return 0;
}

Related

How to sort a string array according to string length in c++?

I'm trying to sort string array in this way. But the first string of the array isn't printing correctly. How can I code it in a easy way? I need to use it for competitive programming. So, it would be great if the code is short.
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
string s[] = {"midnight", "Coder", "comp", "Wedn", "Top", "at"};
int n = sizeof(s)/sizeof(s[0]);
sort(s->begin(), s->end());
for (int i = 0; i < n; i++)
{
cout<<s[i]<<" ";
}
return 0;
}
Output Result: dghiimnt Coder comp Wedn Top at
Output Expected: midnight Coder comp Wedn Top at
In C++20 you would do it like this:
#include <algorithm>
#include <iostream>
int main()
{
std::string s[] = {"midnight", "Coder", "comp", "Wedn", "Top", "at"};
std::ranges::sort(s, std::greater{}, &std::string::size);
for (const auto &it : s)
std::cout << it << " ";
}
std::greater{} means larger elements should come first (as opposed to the default std::less{}).
&std::string::size means we sort by the return value of .size(), as opposed to comparing the elements directly.
I've also fixed some style issues.
One way(probably the simplest) is to use a lambda for this as shown below.
int main()
{
string s[] = {"midnight", "Coder", "comp", "Wedn", "Top", "at"};
int n = sizeof(s)/sizeof(s[0]);
//use lambda
sort(std::begin(s), std::end(s), [](const std::string &a, const std::string &b)
{
return a.size() > b.size();
});
for (int i = 0; i < n; i++)
{
cout<<s[i]<<" ";
}
}
working demo

std::cin string to int array with variable length input

I have a task where i need to revert a list of variable length numbers. This could be "1 2 3" or "5 6 7 8 9 10".
The sorting itself works fine.
But I can't figure out how to read the user input (with variable length) and then only execute the reverseSort once.
How can I read the user input into an array where each index is based on the space between the numbers?
Here is my code:
#include <iostream>
#include <string>
using namespace std;
bool sorted = true;
int temp;
int * arr;
int arrLength = 5;
int arrs;
// int arr = {1,2,3,4,5};
void reverseSort(int arr[], int n){
sorted = true;
for (int i = 0; i < n-1; i++){
if (arr[(i + 1)] > arr[i]){
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
sorted = false;
}
}
if (!sorted){
reverseSort(arr,n);
}
}
int main(void){
// get user input !?!?!?!?!
cin >> arrs;
cout << arrs;
reverseSort(arr,arrLength);
for (int i = 0; i < arrLength; i++){
std::cout << arr[i] << " ";
}
return 0;
}
If you don't know number of inputs you need struct that can be resized. std::vector is good for it. For adding new data you can use member function push_back.
You can read the input line as std::string (by std::getline) and you can open new stream with read data (std::istringstream). Further one can read values from new stream.
And I think you can use std::sort instead of reverseSort (but for 'reverse' you need use std::greater as comparator).
#include <vector>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <algorithm>
int main(void){
std::vector<int> arrs;
// read only one line
std::string input;
std::getline(std::cin, input);
std::istringstream row(input);
int x;
while (row >> x)
{
arrs.push_back(x);
}
//like your reverseSort
std::sort(arrs.begin(), arrs.end(), std::greater<int>{});
for (auto var : arrs) {
std::cout << var << "; ";
}
return 0;
}

How do I read a stringstream into a char *[40] / char ** array?

I am working on creating a UNIX shell for a lab assignment. Part of this involves storing a history of the past 10 commands, including the arguments passed. I'm storing each command as a C++ string, but the parts of the program that actually matter, and that I had no input in designing (such as execve) use char * and char ** arrays exclusively.
I can get the whole command from history, and then read the program to be invoked quite easily, but I'm having a hard time reading into an arguments array, which is a char *[40] array.
Below is the code for a program I wrote to simulate this behavior on a test string:
#include <sstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
char *chars[40];
string test = "Hi how are you";
stringstream testStream;
testStream << test;
int i = 0;
while (true)
{
string test_2;
testStream >> test_2;
if (testStream.fail())
{
break;
};
chars[i] = (char *)test_2.c_str();
i++;
}
for (int i=0; i < 4; i++)
{
cout << chars[i];
}
cout << "\n";
}
I get the feeling it has something to do with the array being declared as an array of pointers, rather than a multi-dimensional array. Am I correct?
This line:
chars[i] = (char *)test_2.c_str();
leaves chars[i] 'dangling' when you go back round the loop or fall off the end. This is because test_2.c_str() is only valid while test_2 is in scope.
You'd do better to do something like this:
#include <sstream>
#include <iostream>
#include <string>
#include <vector>
#include <memory>
int main()
{
std::vector <std::string> args;
std::string test = "Hi how are you";
std::stringstream testStream;
testStream << test;
int i = 0;
while (true)
{
std::string test_2;
testStream >> test_2;
if (testStream.fail())
break;
args.push_back (test_2);
i++;
}
auto char_args = std::make_unique <const char * []> (i);
for (int j = 0; j < i; ++j)
char_args [j] = args [j].c_str ();
for (int j = 0; j < i; ++j)
std::cout << char_args [j] << "\n";
}
Now your vector of strings remains in scope while you are building and using char_args.
Live demo

Displaying all prefixes of a word in C++

I am trying to do is display all the suffixes of a word as such:
word: house
print:
h
ho
hou
hous
house
What I did is:
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char cuvant[100];
int i,k;
cin>>cuvant;
for(i=0;i<strlen(cuvant);i++)
{
for(k=0;k<i;k++)
{
if(k==0)
{
cout<<cuvant[k]<<endl;
}else
{
for(k=1;k<=i;k++){
if(k==i) cout<<endl;
cout<<cuvant[k];
}
}
}
}
}
What am I doing wrong?
You're over-complicating it. Here's a simpler way:
#include <iostream>
#include <string>
#include <string_view>
int main() {
std::string s;
std::cin >> s;
for (std::string::size_type i = 0, size = s.size(); i != size; ++i)
std::cout << std::string_view{s.c_str(), i + 1} << '\n';
}
If you don't have access to a C++17 compiler, you can use this one:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
int main() {
std::string s;
std::cin >> s;
for (auto const& ch : s) {
std::copy(s.c_str(), (&ch + 1),
std::ostream_iterator<decltype(ch)>(std::cout));
std::cout << '\n';
}
}
Even so, I think it would be better for your learning progress to use a debugger to finger out the problem yourself. Here the problems with your code:
For the i=0 (the first iteration of your outer loop) the for(k=0;k<i;k++) will not be executed at all, as k<0 evaluates to false.
And having a running variable (k) that you change in two for loops that are nested, is most of the time also an indication that something is wrong.
So what you want to do: You want to create each possible prefix, so you want to create n strings with the length of 1 to n. So your first idea with the outer loop is correct. But you overcomplicate the inner part.
For the inner part, you want to print all chars from the index 0 up to i.
int main() {
char cuvant[100];
std::cin >> cuvant;
// loop over the length of the string
for (int i = 0, size = strlen(cuvant); i < size; i++) {
// print all chars from 0 upto to i (k<=0)
for (int k = 0; k <= i; k++) {
std::cout << cuvant[k];
}
// print a new line after that
std::cout << std::endl;
}
}
But instead of reinventing the wheel I would use the functions the std provides:
int main() {
std::string s;
std::cin >> s;
for (std::size_t i = 0, size = s.size(); i < size; i++) {
std::cout << s.substr(0, i + 1) << std::endl;
}
}
For this very simple string suffix task you can just use:
void main()
{
std::string s = "house";
std::string s2;
for(char c : s)
{
s2 += c;
cout << s2 << endl;
}
}
For more complicated problems you may be interested to read about Suffix Tree
Your code is wrong, the following code can fulfill your requirements
#include <iostream>
using namespace std;
int main()
{
char cuvant[100];
int i,k;
cin>>cuvant;
for(i=0;i<strlen(cuvant);i++)
{
for (k = 0; k <= i; ++k)
{
cout<<cuvant[k];
}
cout<<endl;
}
}

C++ How to find out most consecutive digits in an array?

Hi guys I'm trying to write a code where when i type a binary string I need to mind the most consecutive numbers of occurrence 1 has occurred. For example, if i type 00111001, it should be 3, 1100111011111, it should be 5 etc. This is my code so far.
int main () {
string s1;
cin >> s1;
int l1=s1.size()-1; // length-1 hence the for loop array doesnt go out of bounds
int max=0; // this tells us the max number of occurrence
int count=0;
for (int i=0;i<l1;i++) {
if (s1[i]=='1' && s1[i+1]=='1') { // if s[0] and s[1] are both 1, it adds 1
count++;}
if (count>0 && count>max)
{max=count; // storing the count value in max.
}
if (s1[i]=='0' || s1[i+1]=='0'){ //resetting count if it encounters 0
count=0;
}
}
max=max+1;
cout << max << '\n' << endl;
The issue is if I write 1111001 it runs (I get 4), but when i type 1100111001 I get 2. Don't get why there's ambiguity. Please let me know what I need to do
Thanks
I'd only increment the count in case of 1, and zero it when 0 is reached.
whenever count is bigger than max, assign count to max and that's it.
btw, I get 3 for the input 1100111001 with your program.
#include <iostream>
using namespace std;
int main() {
string s1;
cin >> s1;
int l1 = s1.size();
int max = 0;
int count = 0;
for (int i = 0; i < l1; i++)
{
if (s1[i] == '1')
{
count++;
}
else
{
count = 0;
}
if (count > max)
{
max = count;
}
}
cout << max << '\n' << endl;
}
Let's solve this using find, given string s1 which contains your input string you can just do:
auto max = 0;
for(auto start = find(cbegin(s1), cend(s1), '1'); start != cend(s1); start = find(start, cend(s1), '1')) {
const auto finish = find(start, cend(s1), '0');
const auto count = distance(start, finish);
if(count > max) {
max = count;
}
start = finish;
}
Live Example
I want to offer you such an option for calculating through tokens and sorting:
#include <string>
#include <vector>
#include <sstream>
#include <algorithm>
using namespace std;
int main()
{
string s1;
cin>>s1;
istringstream s(s1);
vector<string> result;
while (std::getline(s,s1,'0')) {
result.push_back(s1);
}
sort(result.begin(),result.end(),[](const string &a, const string &b){ return a.length()>b.length();});
cout << result.at(0).length() << endl;
return 0;
}