How to sort a string array according to string length in c++? - 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

Related

How to change each specific char to an int in C++

It might be a really dumb question, but I have tried to look it up, and have googled a bunch, but still can't figure out an easy way...
In C++, saying that using namespace std;:
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
String N;
cin >> N;
}
When user input is 123, N will be "123".
How do I cast '1' to int 1, and '2' to int 2, and '3' to int 3?
I cannot use %.
It would be awesome if I were to use an index approach in the string.
I would like to have a function that receives N and its index as parameters. For instance:
int func(string N, int curr_ind)
{
// change curr_ind of N to a single int
// for instance, "123" and 1, it would return 2.
}
#include <iostream>
#include <string>
int get_digit_from_string(const std::string&s, int idx) {
return static_cast<int>(s[idx] - '0');
}
int main() {
std::string num{"12345"};
for (std::size_t i = 0; i < num.length(); ++i) {
std::cout << get_digit_from_string(num, i) << '\n';
}
}
Just get the character at the index, subtract '0', and cast to int.
The subtraction is necessary, otherwise the character of a digit will be cast to the ASCII value of that character. The ASCII value of '0' is 48.
Output:
❯ ./a.out
1
2
3
4
5
Now, just for fun, let's say you need frequent access to these digits. Ideally, you'd just do the conversion all at once and have these ints available to you. Here's one way of doing that (requires C++20):
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
std::vector<int> get_digits_from_string(const std::string& s) {
std::vector<int> v;
std::ranges::transform(s, std::back_inserter(v),
[](auto c) { return static_cast<int>(c - '0'); });
return v;
}
int main() {
std::string num{"12345"};
std::vector<int> digits = get_digits_from_string(num);
for (auto i : digits) {
std::cout << i << '\n';
}
}
We use the string to create a std::vector where each element is an int of the individual characters. I can then access the vector and get whatever digit I need easily.
Another possibility:
#include <iostream>
#include <string>
int main()
{
std::string input;
std::cin >> input;
// allocate int array for every character in input
int* value = new int[input.size()];
for (int i = 0; i < input.size(); ++i)
{
std::string t(1, input[i]);
value[i] = atoi(t.c_str());
}
// print int array
for (int i = 0; i < input.size(); ++i)
{
std::cout << value[i] << std::endl;
}
delete[] value;
}
Output:
x64/Debug/H1.exe
123
1
2
3
Try this:
int func(string N, int curr_ind)
{
return static_cast<int>(N[curr_ind]-'0');
}
Since the ASCII representation of consecutive digits differs by one, all you need to do to convert a character (char c;) representing a digit to the corresponding integer is: c-'0'

C++ string array about nums

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;
}

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;
}
}

How to print frequency of each letter in a string in descending order c++?

#include <iostream>
#include <string>
using namespace std;
int main () {
int cnt[26] {};
char alpha[26];
string s = "abcdefffggghiii";
for (int i = 0; i < s.length(); i++) {
cnt[s[i] - 'a']++;
}
for (int i = 'a'; i <= 'z'; i++) {
alpha[i - 'a'] = i;
}
for (int i = 0; i < 26; i++) {
if (cnt[i]) {
cout << alpha[i] << " " << cnt[i] << endl;
}
}
return 0;
}
I wanted to print the frequencies of each letter in the string in descending order. I've thought to sort the cnt array and print from 25 to 0 but it will only print the frequencies with wrong letter. How can I fix it to print for example i 3 and so on in descending order?
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
// Create result container
auto x = vector<pair<char, int>>();
std::string s = "abcdefffggghiii";
for (auto& l : s) {
// Find the item that corresponds to letter
auto pLetter =
find_if(x.begin(), x.end(), [&l](pair<char, int> &arg) {
return arg.first == l;
});
if (pLetter != x.end())
pLetter->second++; // If item corresponding to letter is found, increment count
else {
x.push_back(make_pair(l, 1)); // Otherwise, create a new result entry
}
}
// Sort results by count in descending order
std::sort(x.begin(), x.end(),
[](auto &left, auto &right) { return left.second > right.second; });
for (auto i = x.begin(); i != x.end(); ++i)
std::cout << i->first << ':' << i->second << '\n';
}
Produces
f:3
g:3
i:3
a:1
b:1
c:1
d:1
e:1
h:1
You can run it here. This uses C++14 lambdas for the find_if and sort predicates. This solution is very similar to #Retired Ninja's, except that the result vector contains items only for those letters that have non-zero counts. This means that it is extendable to wstrings without the need for a large result vector.
Here's how I might do it. You just need to keep the letter and the count together.
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
struct LetterFreq
{
char letter;
int freq;
};
int main()
{
std::vector<LetterFreq> cnt(26);
for (size_t i = 0; i < cnt.size(); ++i)
{
cnt[i].freq = 0;
cnt[i].letter = static_cast<char>(i) + 'a';
}
std::string s = "abcdefffggghiii";
for (auto& l : s)
{
cnt[l - 'a'].freq++;
}
std::sort(cnt.begin(), cnt.end(), [](const LetterFreq& lhs, const LetterFreq& rhs)
{
return lhs.freq > rhs.freq;
});
for (auto& item : cnt)
{
if (item.freq == 0)
{
break;
}
std::cout << item.letter << " : " << item.freq << "\n";
}
return 0;
}
This is simple if all you have it lowercase ASCII letters. For more complicated input you can use the same idea of the letter and count in a struct, but you'd either want to increase the size of the vector to 256 to keep track of all possibilities, or use something like an unordered map to only store used symbols and then copy them out into a container you can sort to display them. You could also use parallel arrays and while sorting swap the letter positions at the same time you're swapping the counts. There are many ways to handle this.
You could use pairs, but it looks like you're doing this with more basic types. In that case you might have to use nested loops. Keep finding the highest frequency character, print it, and then set its frequency to -1 to indicate that you've processed it already.

Comparing two arrays and creating third array with common elements

I need to compare two arrays and output another array that shows common elements.
The output I'm expecting with my code is: 0000056789.
Help will be appreciated.
#include <iostream>
using namespace std;
const int CE = 10;
const int TOP = CE-1;
int iArr1[CE]={0,1,2,3,4,5,6,7,8,9};
int iArr2[CE]={5,6,7,8,9,10,11,12,13,14};
int iArr3[CE]={0,0,0,0,0,0,0,0,0,0};
void main()
{
int i;
int j;
int iCarr3 = 0;
for(i=0; i<=TOP; i++)
{
for (j=0; j<=TOP; j++)
{
if (iArr1[i]==iArr2[j])
{
iCarr3++;
iArr3[iCarr3]=iArr2[j];
}
}
}
cout << iCarr3 << endl;
cout << iArr3;
getchar();
}
you are printing the address of your array
to print the elements of an array
for (int i = 0; i < size; i++) // keep track of the size some how
cout<<iArr3[i]<<" ";
P.S: consider sorting the arrays first, and ckecking if iArr1[i] > iArr2[j]that way you won't need to scan all the elements on eavh pass
C++ has a set_intersection algorithm in the Standard Library:
#include <iostream>
#include <algorithm>
int main()
{
const int CE = 10;
int iArr1[CE] = {0,1,2,3,4,5,6,7,8,9};
int iArr2[CE] = {5,6,7,8,9,10,11,12,13,14};
int iArr3[CE] = {0,0,0,0,0,0,0,0,0,0};
std::set_intersection(std::begin(iArr1), std::end(iArr1),
std::begin(iArr2), std::end(iArr2),
std::begin(iArr3));
std::copy(std::begin(iArr3), std::end(iArr3), std::ostream_iterator<int>(std::cout, " "));
}
Output
5 6 7 8 9 0 0 0 0 0
Note
If your arrays aren't already sorted, you could put the data into a std::set first, since std::set_intersection() requires the inputs to be sorted.
Ok I hope this is not homework. The way you have it, the output will be 5678900000. For the output to be as you want change your code to be as such:
for(i=0; i<=TOP; i++)
{
for (j=0; j<=TOP; j++)
{
if (iArr1[i]==iArr2[j])
{
iArr3[iCarr3]=iArr2[j];
}
}
iCarr3++;
}
Then for the output do this:
for(int k = 0; k <= iCarr3; k++)
std::cout << iArr3[iCarr3] << " ";
As your array are sorted, use std::set_intersection. Otherwise you just have to std::sort them before.
But never forget to use the STD library, the code is a lot more compact and readable... And most of the time less buggy and faster that what you'll come with.
http://ideone.com/c3xE3m
#include <algorithm>
#include <iostream>
#include <iterator>
const size_t CE = 10;
int iArr1[CE]={0,1,2,3,4,5,6,7,8,9};
int iArr2[CE]={5,6,7,8,9,10,11,12,13,14};
int iArr3[CE]={0,0,0,0,0,0,0,0,0,0};
int main(int argc, char const *argv[])
{
auto end_elemnt =
std::set_intersection(iArr1, iArr1 + CE,
iArr2, iArr2 + CE,
iArr3);
std::copy(iArr3, end_elemnt, std::ostream_iterator<int>(std::cout, ", "));
return 0;
}
Here is the output:
$ ./a.exe
5, 6, 7, 8, 9,