String and ascii values - c++

In this piece of code if i run a for loop to know elements stored inside the array c I get output as 1 1 1 0 0 0 0 1 0 0.
The input is abc. Why it does it give 1 1 1 instead of 0 1 2 0 0 0 0 0 0?
int c[26]={};
cin >> s;
len = s.length();
for(int i = 0 ; i < len ; i++ ){
c[s[i] - 'a'] ++ ;
}

Your c array is a histogram of the characters read. Your output is saying you read 1 'a', 1 'b' and 1 'c'. Try c[s[i] - 'a'] = s[i] - 'a';

Your code is basically counting the number of letters in a string. The count is stored in the array c where the index represents the letter index in the alphabet. So a is 0, b is 1, c is 2 and so on.
So for abc the correct input is indeed 1 1 1, due to the fact that there's 1 a, 1 b and 1 c. Your 0 1 2 would represent a string with 1 b and 2 cs.

s[i] - 'a'
That is returning 0, 1 and 2. But
c[s[i] - 'a'] ++ ;
Is always increasing 1 each occurrence of C[] which at the beginning was initializing with all zeros. For that reason you get all 1s in your output.
Try
c[s[i] - 'a'] = s[i] - 'a'

Related

C++ string push_back function not working

I am trying to generate strings with {0, 1, 2} using an integer queue to store numbers until I am ready to check if they are binary numbers. I am starting with single digits and then appending them to get longer and longer number strings. So the order I am trying to get is 0, 1, 2, 00, 01, 02, 10, 11, 12, 20, 21, 22, 000, 001, 002, 010, 011, 012 e.t.c. The problem I am having though is that when I dequeue an integer from my queue, turn it into a string and try to append it with {0, 1, 2} using s.push_back(app), nothing is appended. Below is my code and output.
int main()
{
string s; //holds strings of numbers that come from the int queue
bool isBin; //holds the boolean value returned from recognizer
int count=0; //while loop counter to not go over 20 iterations
Queue myQ; //queue created to hold all values generated
int numHolder; //holds values dequeued from int queue to be turned into string
myQ.enQueue(0);//queue 3 initial values to work with
myQ.enQueue(1);
myQ.enQueue(2);
while(count<=20)//while loop doesnt go over 20 iterations of binary numbers
{
numHolder=myQ.deQueue();//holds int values dequeued from queue
s=to_string(numHolder);//converts the int from queue to a string
/* isBin=recognizer(s);//send the string to the recognizer
if(isBin==true)
{
cout<<s<<endl;//prints string if it is binary number
count++;//increment counter because string was binary
}*/
for(int i=0; i<3; i++)//this loop adds 0 then 1 then 2 to the end of each dequeued string
{
char app = i;
s.push_back(app);//this is where string is appended with 0 1 or 2
cout<<s<<endl;
int newNum=stoi(s);//new appended string is turned into integer
myQ.enQueue(newNum);//new integer is put into queue
s.pop_back();//pops back the string so other numbers can be created with the original dequeued string
}
count++;
}
// }// end of while
}// end of main
output:
0
0
0
1
1
1
2
2
2
0
0
0
0
0
0
0
0
0
1
1
1
1
1
1
1
1
1
2
2
2
2
2
2
2
2
2
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
I can tell by the output it has the right order for the first characters but nothing is being appended to them because the string push_back function is not working. Please help!
char app=i stores the characters whose binary value is 0 1 and 2, not the characters '0', '1' and '2'.
Try char app = '0'+i;
In C/C++ char is both a number type and the traditional way to store a single character. The conversion from int just treats char like a number type.

Matlab - Convert Character Vector Into Number Vector?

I'm trying to implement an oscilloscope for a digital input and send it over a serial port for debugging. I have the scope software sending Matlab a string like "000000111111111000000001111111000000". I'd like to plot this. Is there any way for me to split this string into a vector. It doesn't seem Matlab allows you to use strsplit() without a delimiter. I'd rather not bog up the communications with a delimiter between each byte.
With MATLAB's weak typing, this is actually quite easy:
>> str = '000000111111111000000001111111000000'
str = 000000111111111000000001111111000000
>> class(str)
ans = char
>> vec = str - '0'
vec =
Columns 1 through 22:
0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0
Columns 23 through 36:
0 1 1 1 1 1 1 1 0 0 0 0 0 0
>> class(vec)
ans = double
This subtracts the ordinal value of the character '0' from each character in the string, leaving the numerical values 0 or 1.
You can use sscanf with a single value width:
a = '000000111111111000000001111111000000'
b = sscanf(a, '%1d');
Which returns:
>> b.'
ans =
Columns 1 through 18
0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0
Columns 19 through 36
0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0
A quick and fast solution is:
data = '000001111111110000000000111111111110000000';
vec = str2double(cellstr(data.').');
It will produce a column vector of numeric values. If you want a row vector as output, just use a single transpose:
vec = str2double(cellstr(data.'));
I'm surprised how difficult this is to do. But here's what I came up with:
str = '000001111111110000000000111111111110000000'; %test string
y = cellfun(#(x) str2num(x), regexp(str,'\d','match'));
plot(y);
regexp() seems to be the only way to go. By default, it return indexes of matches so you need to specify 'match'. Then you end up with a cell array of strings. The only good way to convert this into a numerical array is one item at a time with str2num().
I hope this helps someone else out who is assuming there is a straight forward function as I assumed. And if anyone knows a way to do this without converting my "01...01....01....01....00....00....00....00" stream of bytes into the ascii representations of the binary numbers: "49.....49.....49....49....48....48....48....48", I'd love to hear it.

How to fix a bug in my homework solution in C++?

I need to write a program which reads the statistics of n League A football teams and prints the teams name which fall in League B.
A team falls in League B, if it has less than k points after having played m weeks where m is between 1 and 150. Each team gets three points for a win, one point for draw and zero points when lost.
Input Specification: In the first line, you will be given the number of teams 0 < n ≤ 500 and the points 0 < k ≤ 300 needed to stay in league A. Then in the following n lines, there will be the team name and its results. Semicolon indicates the end of input series.
Number 2 represents win, number one represents draw and number zero represents loss.
Output specification:
Sample Input I
4 19
Team_A 1 1 1 1 1 1 1 1 1 0 1 1 1 0 2 1 0 ;
Team_B 0 1 0 2 2 1 1 0 1 1 0 2 0 1 0 0 2 ;
Team_C 0 0 1 0 2 2 2 1 1 1 1 1 0 0 2 1 2 ;
Team_D 0 1 0 1 2 1 2 1 0 0 0 2 2 2 0 0 0 ;
Sample Output I
Team_A 16
Team_B 18
This is the code I came up with, but the output is wrong and I don't know why,
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int n,points,sum=0,i,value;
char name[15];
char p;
scanf("%d %d",&n,&points);
for(i=1;i<=n;i++)
{
scanf("%s",&name);
do
{
scanf("%c ",&p);
if(p!=';')
{
value=p-48;
sum=sum+value;
}
}while(p!=';');
if(sum<=points)
printf("%s %d",name,sum);
}
return 0;
}
You might look for problems by stuffing the program with output statements.
If you add after scanf("%c ",&p); an output statement to show the value of p, you will find that the first value for p is a space character, which spoils your calculation.
In the same way, if you trace the value of value, you will find that you forgot to initialize this variable to zero for each team.

Ordering an array based on 2D array of relations (higher, lower, doesn't matter)

I have been stuck with this problem for two days and I still can't get it right.
Basically, I have a 2D array with relations between certain numbers (in given range):
0 = the order doesn't matter
1 = the first number (number in left column) should be first
2 = the second number (number in upper row) should be first
So, I have some 2D array, for example this:
0 1 2 3 4 5 6
0 0 0 1 0 0 0 2
1 0 0 2 0 0 0 0
2 2 1 0 0 1 0 0
3 0 0 0 0 0 0 0
4 0 0 2 0 0 0 0
5 0 0 0 0 0 0 0
6 1 0 0 0 0 0 0
And my goal is to create a new array of given numbers (0 - 6) in such a way that it is following the rules from the 2D array (e.g. 0 is before 2 but it is after 6). I probably also have to check if such array exists and then create the array. And get something like this:
6 0 2 1 4 5
My Code
(It doesn't really matter, but I prefer c++)
So far I tried to start with ordered array 0123456 and then swap elements according to the table (but that obviously can't work). I also tried inserting the number in front of the other number according to the table, but it doesn't seem to work either.
// My code example
// I have:
// relArr[n][n] - array of relations
// resArr = {1, 2, ... , n} - result array
for (int i = 0; i < n; i++) {
for (int x = 0; x < n; x++) {
if (relArr[i][x] == 1) {
// Finding indexes of first (i) and second (x) number
int iI = 0;
int iX = 0;
while (resArr[iX] != x)
iX++;
while (resArr[iI] != i)
iI++;
// Placing the (i) before (x) and shifting array
int tmp, insert = iX+1;
if (iX < iI) {
tmp = resArr[iX];
resArr[iX] = resArr[iI];
while (insert < iI+1) {
int tt = resArr[insert];
resArr[insert] = tmp;
tmp = tt;
insert++;
}
}
} else if (relArr[i][x] == 2) {
int iI = 0;
int iX = 0;
while (resArr[iX] != x)
iX++;
while (resArr[iI] != i)
iI++;
int tmp, insert = iX-1;
if (iX > iI) {
tmp = resArr[iX];
resArr[iX] = resArr[iI];
while (insert > iI-1) {
int tt = resArr[insert];
resArr[insert] = tmp;
tmp = tt;
insert--;
}
}
}
}
}
I probably miss correct way how to check whether or not it is possible to create the array. Feel free to use vectors if you prefer them.
Thanks in advance for your help.
You seem to be re-ordering the output at the same time as you're reading the input. I think you should parse the input into a set of rules, process the rules a bit, then re-order the output at the end.
What are the constraints of the problem? If the input says that 0 goes before 1:
| 0 1
--+----
0 | 1
1 |
does it also guarantee that it will say that 1 comes after 0?
| 0 1
--+----
0 |
1 | 2
If so you can forget about the 2s and look only at the 1s:
| 0 1 2 3 4 5 6
--+--------------
0 | 1
1 |
2 | 1 1
3 |
4 |
5 |
6 | 1
From reading the input I would store a list of rules. I'd use std::vector<std::pair<int,int>> for this. It has the nice feature that yourPair.first comes before yourPair.second :)
0 before 2
2 before 1
2 before 4
6 before 0
You can discard any rules where the second value is never the first value of a different rule.
0 before 2
6 before 0
This list would then need to be sorted so that "... before x" and "x before ..." are guaranteed to be in that order.
6 before 0
0 before 2
Then move 6, 0, and 2 to the front of the list 0123456, giving you 6021345.
Does that help?
Thanks for the suggestion.
As suggested, only ones 1 are important in 2D array. I used them to create vector of directed edges and then I implemented Topological Sort. I decide to use this Topological Sorting Algorithm. It is basically Topological Sort, but it also checks for the cycle.
This successfully solved my problem.

Bitwise operation to get 1 if both are 0

I'd need to perform a bitwise operation (or a serie) so that:
0 1 = 0
1 1 = 1
1 0 = 0
so far AND (&) works fine but I also need that
0 0 = 1
and here AND (&) is not the correct one.
I'm using it in a jquery grep function that reads:
jQuery.grep(json, function (e, index) {
return (e.value & (onoff << 3)) != 0;
});
where onoff could be either 1 or 0 and e.value is a representation of a 4 bits string (i.e. could be "1001"). In this above example I'm testing first bit on the left (<< 3).
Can this be done with a serie of AND, OR, XOR?
This is just XNOR(a, b), which is equal to NOT(XOR(a, b)), i.e. exclusive OR with the output inverted. In C and C-like languages this would be:
!(a ^ b)
or in your specific case:
return !((e.value >> 3) ^ onoff);
Having said that, you could just test for equality:
return (e.value >> 3) == onoff;
This looks roughly like XOR which has the following results table:
0 0 = 0
0 1 = 1
1 0 = 1
1 1 = 0
Now you want to have the opposite, meaning that you want 1 if both inputs are the same value. And this leads us to NOT XOR
0 0 = 1
0 1 = 0
1 0 = 0
1 1 = 1