problem:
Given a matrix of integers, count the amount of times each number 0-9 appears. Print out your results on one line in the following form:
0:number of zeros;1:number of ones;2:number of twos;3:number of threes;4:number of fours;5:number of fives;6:number of sixes;7:number of sevens;8:number of eights;9:number of nines;
For example, if you are passed an identify matrix, it contains 12 zeros and 4 ones and no other numbers from 0 to 9, your output would be:
0:12;1:4;2:0;3:0;4:0;5:0;6:0;7:0;8:0;9:0;
So far I have been created some codes:
#include<bits/stdc++.h>
using namespace std;
void printfrequency(int array[][4])
{
int c=0;
for(int a=0; a<10; a++){
for (int i=0; i<4; i++)
for ( int j=0;j<4;j++)
if(array[i][j] == a){
c++;
}
cout << a << ":" << c <<";" ;
}
}
int main()
{
int array[4][4] = { {3,5,7,9}, {2,4,8,9},{1,1,1,1},{3,6,9,2} };
printfrequency(array);
return 0;
}
and here is the ouput:
0:0;1:4;2:6;3:8;4:9;5:10;6:11;7:12;8:13;9:16;
How can I achieve 0:12;1:4;2:0;3:0;4:0;5:0;6:0;7:0;8:0;9:0; ?
The code you show gives output based on the frequencies for the specific array init visible in the shown code.
That array init contains no zeros, so the output should start with "0:0" and it does. (Actually required for the shown array init would be "zeros:0", but I stick with your codes basic concept of output and only discuss frequency values).
The output mentioned as example in the assignemnt is for an "identity" matrix, though you have a typo there. Such an identity matrix has a diagonal of "1"s in other wise all "0"s. Counting them gives the output of 4 ones and 12 zeros for a 4 by 4 matrix as shown.
The code is not correct, it fails to reset the count and the frequencies hence increase over the output.
To fix that mistake (but still get the frequencies for the array init, not the example output) change
int c=0;
for(int a=0; a<10; a++)
{
to
for(int a=0; a<10; a++)
{
int c=0;
That will reset the count for each digit your are counting and get you the output:
0:0;1:4;2:2;3:2;4:1;5:1;6:1;7:1;8:1;9:3;
All answers are given, correct and accepted.
But additionally I would like to give some hints for a "better" C++ programming style.
We can see in your code that you maybe try to learn from some "Hacker" or "competition" site. That will never work. If you really want to learn C+, then start with books or serious sites.
What we can see in your code:
#include<bits/stdc++.h> is not compliant C++ code. The header file is an extension available for some compilers.But you should never use it.
using namespace std; should never be used. Please use fully qualified names and to not pull in the complete std::namespace
Prefer pre-increment overpost-increment, whereever possible
Do not use C-Style arrays in C++. Use C++ instead.
Variable names should be expressive
Add comments. The more, the better.
Then, without changing any algorithm or structure of your original program and just modifying the names and adding comments, your code could look like the below:
#include <iostream>
#include <array>
// We want to have a square matrix with 4 rows and 4 coulmns
constexpr unsigned int MatrixSize = 4;
// Save some typing work and make array definition more readable
using SquareMatrix = std::array<std::array<int, MatrixSize>, MatrixSize >;
// Function to print thr frequency of interges in a matrix in the range 0..9
void printFrequencyOfNumbersIn(SquareMatrix& squareMatrix) {
// Check all interger digits in the range 0..9
for (int digit = 0; digit < 10; ++digit) {
// The initial counter value for this digit will always start with 0
int digitCounterForThisDigit = 0;
// Now, iterate over all rows
for (int row = 0; row < MatrixSize; ++row)
// And then iterate over all columns of that row
for (int column = 0; column < MatrixSize; ++column)
// CHeck, if the value in the matrix is equal to the current evaluated digit
if (squareMatrix[row][column] == digit)
// If so, then increment counter
++digitCounterForThisDigit;
// And show the frequency count for the digit under evaluation
std::cout << digit << ':' << digitCounterForThisDigit << ';';
}
}
int main() {
// Define and initialize our squre matrix
SquareMatrix matrix = { {{3,5,7,9}, {2,4,8,9},{1,1,1,1},{3,6,9,2}} };
// Let the subfunction analyze and print the frequencies
printFrequencyOfNumbersIn(matrix);
return 0;
}
This is by far more better understandbale than the original version. Functionality wise it is the same.
And, if you want a "more modern" C++ approach, then you would use a std::map or std::unordered_map. That is the idiomatic correct approach for frequency calculation.
This would then look like that:
#include <iostream>
#include <map>
#include <array>
#include <algorithm>
using MyTpe = int;
// Save some typing work. This will define a square matrix with data of type T
// and rows/columns size equal to template parameter MatrixSize
template <typename T, size_t MatrixSize >
using SquareMatrix = std::array<std::array<T, MatrixSize>, MatrixSize>;
// Here we make an abbreviation for our square matrtx that should consist of 4 rows and 4 columns of ints
using MySquareMatrix = SquareMatrix<MyTpe, 4u>;
// Print frequency of any interger in the matrix
void printFrequencyOfNumbersin(MySquareMatrix& mySquareMatrix) {
// Standard idiomatic approach for counting elements
std::map<MyTpe, size_t> counter{ {0,0u}, {1,0u}, {2,0u}, {3,0u}, {4,0u}, {5,0u}, {6,0u}, {7,0u}, {8,0u}, {9,0u} };
// Go through all rows and columns of the matrix
for (const auto& row : mySquareMatrix) for (MyTpe columnValue : row)
// Count occurence of cell value
counter[columnValue]++;
// Show result to user
for (const auto [number, count] : counter) std::cout << number << ':' << count << ';';
}
int main() {
// Test Data
MySquareMatrix matrix = { {{3,5,7,9}, {2,4,8,9},{1,1,1,1},{3,6,9,2}} };
// Evaluate and print
printFrequencyOfNumbersin(matrix);
return 0;
}
Here is a solution.
#include<bits/stdc++.h>
using namespace std;
int main(){
map<int,int>mp;
int array[4][4] = { {3,5,7,9},{2,4,8,9},{1,1,1,1},{3,6,9,2} };
mp[0]=0,mp[1]=0, mp[2]=0,mp[3]=0, mp[4]=0,mp[5]=0,mp[6]=0,mp[7]=0,mp[8]=0,mp[9]=0;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
int x=array[j][i];
mp[x]++;
}
}
for(auto it=mp.begin();it!=mp.end();it++){
cout<<it->first<<":"<<it->second<<";";
}
}
I wrote this program to find if a string is contained in another string (see paragraph below this, I tried to explain what I want it to do). When I test it, sometimes it works, most of the times it gives me the error "String subscript out of range". I'm very new to C++, I'd appreciate someone to tell me how can I improve this code or why I'm being dumb, because I really don't get why it doesn't work.
what i want this to do is find if string one can be found in string way;
so i want it to check for every letter of string way if the letter [i] is equal to the first letter of the string one (way[i+0]==one[0]),
and way[i+1]==one[1] and so on for all letters in one.
so for example way = abankjve and one = ank
it takes the first letter in way (a) and gets the first letter in one(a). the're equal. but we see that way[0+1] is not equal to one[1]. so o can't be true.
it goes on like this till it gets to way[2]=a. way[2+0]=one[0]. o is true. then it checks way[2+1]=one[1]. true! then it checks way[2+2]=one[2]. true! then
one is contained in way.
#include <iostream>
using namespace std;
int main()
{
string way, one;
bool o=false;
cin >> way;
cin >> one;
for (int i = 0; i < way.size(); i++)
{
for (int k = 0; k < one.size(); k++)
{
if (way[i + k]==one[k])
{
o = true;
}
}
}
cout << o << endl;
}
If you think about it, way[i+k] will result in index out of range.
say way is length of 5 and one is length of 3.
i+k's range is 0 <= i + k <= 6. Witch is bigger than the possible index of way.
change first for loop for (int i = 0; i < way.size(); i++) to
for (int i = 0; i <= (int)way.size() - one.size(); i++)
Note I've used static_cast to int. *.size() returns unsigned int so if one's size is bigger than way's size, the result won't be what you've imagined.
#include <iostream>
#include <string>
int main()
{
std::string way, one;
std::cin >> way;
std::cin >> one;
bool found{};
for (size_t i = 0; i < way.size() - one.size()+1; i++)
{
if(one == way.substr(i, one.size())) {
found = true;
break;
}
}
std::cout << found;
}
Demo
I am trying to solve a question:
An operation consists of selecting k consecutive equal characters and removing them. This operation is to be performed as long as possible. Return the final word after all the operations have been performed. For e.g., for abbcccb and k=3, the output should be a.
The code that I could come up with is as follows:
#include<iostream>
#include<string>
#include<unordered_set>
using namespace std;
string helper(string& s, int k) {
if(s.size()<k) return s;
string str;
for(int i=0; i<s.size(); i++){
char currChar=s[i];
int j=i+1, count=0;
while(j<s.size() && count<=k && s[j]==currChar) {
j++;
count++;
}
if(j-i==k) {
for(int k=0; k<i; k++) str.push_back(s[k]);
for(int k=j; k<s.size(); k++) str.push_back(s[k]);
break;
}
}
if(str.empty()) return s;
return helper(str, k);
}
int main() {
// string s="abbcccb";
// string s="abcdef";
// string s="baac";
string s="aba";
cout<<helper(s, 2);
return 0;
}
Working code here.
However, I think there is a possible way to optimize the code further, especially the part where I determine if k consecutive characters are equal.
Could someone please provide few pointers/ideas/solution?
Thanks.
This is a standard problem that can be solved using stack in O(n) time. Full explanation is already given on this site. Please refer this Reduce the string by removing K consecutive identical characters
I'm struggling with solving this problem in C++.
I have a string: {A,A,B,C} and I want to print all possible permutations for this.
This would be 12:
AABC, AACB, ABAC, ABCA, etc...
I've written the following piece of code in which I have:
- a string which contains the letters A,A,B,C.
- a result string in which I will print each permutation when base condition of recursivity is fullfilled
- an array of integers which represent counters values for each digit: counters[3] = {2,1,1} which means there can be 2 A's, 1 B and 1C in a permutation.
- a function which should solve the problem in a recursive manner like this:
Start from initial string. From left to right of string check if counter for each character is greater than 0. If it is put the character in result[lvl] where lvl is the depth of the recursion. Then decrement the counter for that character's position. Do that for all the elements to the right of the current element and then backtrack all the way up and start with next element(second A).
The base case would be when all counters are equal to 0 print the solution then return.
Here is the code:
#include <iostream>
using namespace std;
char theString[4] = {'A','A','B','C'};
char resultString[4]={};
int counters[3] = {2,1,1};
void printPermutation()
{
for(int i=0; i<4; i++)
{
cout << resultString[i];
}
cout << endl;
}
void solvePermutations(int *counters, int lvl)
{
if(lvl == 4)
{
printPermutation();
return;
}
for(int i=0; i<4; i++)
{
if(counters[i] == 0)
{continue;}
else
{
resultString[lvl] = theString[i];
counters[i]--;
solvePermutations(counters, lvl+1);
counters[i]++;
}
}
}
int main()
{
int *ptr;
ptr = counters;
solvePermutations(ptr, 0);
return 0;
}
When I run the code I get this output instead of what I'm expecting(12 distinct permutations):
ACAB
ACBA
BAAA
BAAC
BACA
etc
More than 12 and with no logic(to me :D)
Please help me correct this and tell me what is wrong in my algorithm and help me understand it. Thank you.
You have one small logical error in your algorithm. You are using a counter[3] and a theString[4]. The idea here is that each index of counter should correspond to one letter, and hold the amount of that letter used.
With your loop you are using i<4. When i is 3 in that loop, you are trying to access counter[3] which is out of bounds. This in undefined behavior and you could be reading any int value.
To correct this, you simply need to decrease the loop to go to max 2 (i < 3) and change theString to an array of 3 elements, {'A', 'B', 'C'}.
char theString[3] = {'A','B','C'};
//...
for(int i=0; i<3; i++)
Sorry for the title, but I really have no idea what the problem is. The code looks like that (here it has no sense, but in the bigger project is has, so please, do not ask "why do you want to do....")
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
string sort (string slowo){
string litery = slowo;
for (int i=0; i<litery.length()-1; i++)
for (int j=0; j<litery.length()-1; j++)
if (litery[j]>litery[j+1])
swap(litery[j], litery[j+1]); // (3)
return litery;
}
int main()
{
fstream wordlist;
wordlist.open("wordlist_test",ios::in);
vector<string> words;
while (!wordlist.eof()){ // (4)
bool ok = true;
string word;
getline(wordlist,word);
string sorted = sort(word);
if (ok){
cout<<word<<endl; // (1)
words.push_back(word);
}
}
for (int i = 0; i<words.size(); i++){
cout<<words[i]<<endl; // (2)
}
}
There are for words in file "wordlist_tests". Program at the end should just write them to vector and write what's in vector into standard output. The problem is:
however line(1) proves that all words are ok
vector appears to be
empty in line (2)
now iteresting (probably just for me) part:
there are two ways to make it right:
I can just remove line(3) (however, if I am right, as the variable is passed to sort function through the value, it just swap two letters in independent variable; it has nothing to do with my vector), or:
I can change condition in while loop (4).
for example just like this:
int tmp = 0;
while (tmp < 5){
tmp++;
/..../
What is wrong with this code? What should I do write these words down to vector but still sort them and using this while loop? I cannot find the connection between this things (ok, I see that connection is variable word, but I do not know in what way). Any help appreciate.
What happens in swap() if one of the words is the empty sting ""?
If this happens, litery = "".
The condition in the loops will be to iterate from 0 to (unsigned) 0 - 1, which is a very large number.
You'll then execute if (litery[0] > litery[1])
litery[1] will access beyond the end of the empty string, which causes undefined behavior.
Let's fix this:
The common fix for this, is to iterate from 1 to string.length(). Here's an example:
string sort (string litery){
for (int i=1; i<litery.length(); i++)
for (int j=1; j<litery.length(); j++)
if (litery[j-1]>litery[j])
swap(litery[j-1], litery[j]);
return litery;
}