I have to capitalize the first and last name in my string array, but I'm stuck on how to access the specific value after I input my string value into an array.
Here are my two functions, the first one reads the values into two separate arrays, and the second is supposed to capitalize the first and last names while changing all other characters to lower case.
void read(string names[],int DVDrent[],int& n)
{
n=0; // # of data calculated
cin >> names[n] >> DVDrent[n]
while(cin)
{
n++;
cin >> names[n] >> DVDrent[n];
}
}
void reformat(string& names)
{
int nlen;
nlen = names.length();
names[0] = toupper(names[0]);
for (int i=1; i<nlen; i++)
{
if (names[i] == ',')
names[i+1] = toupper(names[i+1]);
names[i+2] = tolower(names[i+2]);
}
}
My second function works if I do simply store my data as a string. I'm stuck right now because I'm not sure how to read the specific characters of my array.
For reference, the data that I enter is as follows.
./a.out < data > output
Data:
smith,EMILY 3
Johnson,Daniel 2
williAMS,HanNAH 0
joneS,Jacob 4
bROwn,MicHAEL 5
DAVIS,ETHAn 2
millER,soPhiA 0
TAYlor,matthew 1
andERSON,aNNa 7
Desired output:
Smith,Emily 3
Johnson,Daniel 2
William,Hannah 0
.
.
.
Anderson,Anna 7
etc.
Try this for your reformat() method:
void reformat(string& names) {
bool isUpper = true; // store if the next letter should be upper
for(size_t i = 0; i < names.length(); ++i) {
if (names[i] == ',') {
isUpper = true; // if it's a comma, make the next letter upper
}
else if (isUpper) {
names[i] = toupper(names[i]);
isUpper = false; // make the next letter lower
}
else {
names[i] = tolower(names[i]);
}
}
}
Related
I'm trying to write a program that reads lines of code from a file as strings then splits that string into tokens around each comma. (It is a comma seperated file).
It works for the most part but I'm losing the last token on every single line.
//This is function splits input strings into tokens. It takes in an input
string
//and a delimiter character as parameters.
vector<string> tokenize(string inputString, char delimiter) {
//the store the delimiter in local variable
char newDelimiter = delimiter;
//store the input string in local variable
string newString = inputString;
//vector of strings to store tokens.
vector<string> tokenVector;
//temp variable for making tokens
string temp;
//iterate through the string...
for (int i = 0; i < newString.size(); ++i) {
//...checking for specified delimiter.
//If not present, add current character to temp string.
if (newString.at(i) != newDelimiter) {
temp += newString.at(i);
}
//if present, add temp string to vector and reset temp variable
else
{
tokenVector.push_back(temp);
temp = "";
}
}
return tokenVector;
}
int main() {
//string variable input will store each line of input
string input;
//use getline initially to "skip" the header line
getline(cin, input);
//this vector will be used to store each input lines string tokens
vector<string> stringTokens;
//this while loop will execute as long as cin is reading lines from the
file
while (getline(cin, input)) {
//print out each original line for testing purposes
cout << input << endl;
//split the string into tokens around commas
stringTokens = tokenize(input, ',');
//TEST OUTPUT
for (int j = 0; j < stringTokens.size(); ++j) {
cout << stringTokens.at(j) << " ";
}
cout << endl;
}
return 0;
}
A sample line of output: THere is a zero missing from the second line. The first line is simply the original string, the second the output:
1,000010007,01,XX,0,0,0,0,0,0,0,01 - XXXXX,XXXXXXXXXX,0,0,0,0,0,0,0,0,0,0,0
1 000010007 01 XX 0 0 0 0 0 0 0 01 - XXXXX XXXXXXXXXX 0 0 0 0 0 0 0 0 0 0
How shall I fix this? Thanks.
After the loop add:
if (temp != "")
{
tokenVector.push_back(temp);
}
For the last element.
vector<string> tokenize(string inputString, char delimiter) {
...Code...
for (int i = 0; i < newString.size(); ++i) {
...Code...
}
if (temp != "") {
tokenVector.push_back(temp);
}
return tokenVector;
}
If i want an integer input, but if it contains any digits 2 or 3 in it, it will be rejected.
For example entering 23564 will be invalid.
I was thinking of using do-while loops to solve this, but how do I get it to read the individual digits.
Have a look here:
#include <iostream>
using namespace std;
int main() {
int n,num,flag;
do{
cout<<"Enter number";
cin>>n;
num = n;
flag = 0;
while(num>0)
{
if(num%10 == 2 || num%10 ==3)
{
flag = 1;
break;
}
num = num/10;
}
}while(flag==1);
return 0;
}
If you don't care much about performance, you can convert the integer into a string and look for the digits. This is slower than extracting the last digit and comparing it though.
std::string str = std::to_string(number);
auto found2 = str.find('2');
auto found3 = str.find('3');
//number is valid if it doesn't have a 2 or a 3
bool isValid = found2 == std::string::npos && found3 == std::string::npos;
You can get the last digit of a number with something like:
unsigned int number = 23456;
unsigned int digit = number % 10; // gives 6
You can further "shift" all digits right with:
number = number / 10; // gives 2345
In other words, yes, you can do it using the method you propose:
bool has2Or3(unsigned int number) {
// Do until no more digits left.
while (number != 0) {
// Get last digit, return true if 2 or 3.
int digit = number % 10;
if ((digit == 2) || (digit == 3)) {
return true;
}
// Prepare to get next digit.
number = number / 10;
}
// If NO digits were 2 or 3, return false.
return false;
}
Another way would be to simply convert it to a string and use the string functions to see if it contains a specific digit, something such as:
bool has2Or3(unsigned int number) {
// Get number as string (via string stream).
std::stringstream ss;
ss << number;
std::string s = ss.str();
// If contains 2, return true, else continue.
if (s.find("2") != std::string::npos)
return true;
// If contains 3, return true, else return false.
return (s.find("3") != std::string::npos);
}
Instead of reading the input directly into an integer type, read it into a std::string. Then it's simple to check for unwanted digits; if the string passes the test, convert it to an integer:
int get_value() {
std::string bad = "23";
std::string input = "2"; // start with bad input
while (std::find_first_of(input.begin(), input.end(),
bad.begin(), bad.end()) != input.end()) {
std::cout << "Gimme a number: ";
std::cin >> input;
}
return std::stoi(input);
}
A string is called to be good if and only if "All the distinct characters in String are repeated the same number of times".
Now, Given a string of length n, what is the minimum number of changes we have to make in this string so that string becomes good.
Note : We are only allowed to use lowercase English letters, and we can change any letter to any other letter.
Example : Let String is yyxzzxxx
Then here answer is 2.
Explanation : One possible solution yyxyyxxx. We have changed 2 'z' to 2 'y'. Now both 'x' and 'y' are repeated 4 times.
My Approach :
Make a hash of occurrence of all 26 lowercase letters.
Also find number of distinct alphabets in string.
Sort this hash array and start checking if length of string is divisible by number of distinct characters.If yes then we got the answer.
Else reduce distinct characters by 1.
But its giving wrong answers for some results as their may be cases when removing some character that has not occur minimum times provide a good string in less moves.
So how to do this question.Please help.
Constraints : Length of string is up to 2000.
My Approach :
string s;
cin>>s;
int hash[26]={0};
int total=s.length();
for(int i=0;i<26;i++){
hash[s[i]-'a']++;
}
sort(hash,hash+total);
int ans=0;
for(int i=26;i>=1;i--){
int moves=0;
if(total%i==0){
int eachshouldhave=total/i;
int position=26;
for(int j=1;j<26;j++){
if(hash[j]>eachshouldhave && hash[j-1]<eachshouldhave){
position=j;
break;
}
}
int extrasymbols=0;
//THE ONES THAT ARE BELOW OBVIOUSLY NEED TO BE CHANGED TO SOME OTHER SYMBOL
for(int j=position;j<26;j++){
extrasymbols+=hash[j]-eachshouldhave;
}
//THE ONES ABOVE THIS POSITION NEED TO GET SOME SYMBOLS FROM OTHERS
for(int j=0;j<position;j++){
moves+=(eachshouldhave-hash[j]);
}
if(moves<ans)
ans=moves;
}
else
continue;
}
Following should fix your implementation:
std::size_t compute_change_needed(const std::string& s)
{
int count[26] = { 0 };
for(char c : s) {
// Assuming only valid char : a-z
count[c - 'a']++;
}
std::sort(std::begin(count), std::end(count), std::greater<int>{});
std::size_t ans = s.length();
for(std::size_t i = 1; i != 27; ++i) {
if(s.length() % i != 0) {
continue;
}
const int expected_count = s.length() / i;
std::size_t moves = 0;
for(std::size_t j = 0; j != i; j++) {
moves += std::abs(count[j] - expected_count);
}
ans = std::min(ans, moves);
}
return ans;
}
Given that a string can vary from 2 to 7 characters. I need to fill * to make it up to 7 characters and store all the permutations to a container. In addition, it cannot accept three or more continuous * (e.g. ABCD*** won't be pushed to the container). Also the order of the characters cannot be changed.
For example, a string 'ABCDEF' filled with '*' could have the following permutations:
ABCDEF*
ABCDE*F
ABCD*EF
ABC*DEF
AB*CDEF
A*BCDEF
*ABCDEF
A string 'ABCD' filled with '*' could have the following permutations (note: ABCD*** not accepted because it has 3 continuous '*'):
ABC*D**
ABC**D*
AB*CD**
AB*C*D*
AB*C**D
...
**A*BCD
(...total 30 items will be pushed to the container)
I try to write a program to do this. If the string are 2 characters long, I need to loop 2 times. For example,
void loop_two_times(const std::string & str = "AB")
{
for (int i = 0; i < 7; i++)
{
for (int j = i+1; j < 7; j++)
{
std::string ustring = get7StarsString(); // this string will contain 7 stars
ustring[i] = str[0];
ustring[j] = str[1];
if (!tooMuchStars(ustring))
{
permutations.push_back(ustring);
}
else {} // do nothing
}
}
}
If the string are N characters long, I need to loop N times. However, I do not want to check the number of characters and write the functions to loop 2,3,4,5,6 times. e.g.
switch (numOfChars)
{
case 2: loop_two_times(); break;
case 3: loop_three_times(); break;
case 4: loop_four_times(); break;
case 5: loop_five_times(); break;
case 6: loop_six_times(); break;
}
Please could you kindly suggest how can I implement this efficently?
Many thanks!
You may use the following: (https://ideone.com/L209jH)
// return a string with '0' replaced with letter, and '1' with '*'.
std::string convert(const std::string& order, const std::string& s)
{
std::string res;
std::size_t pos = 0;
for (std::size_t i = 0; i != order.size(); ++i) {
if (order[i] == '1') {
res += '*';
} else {
res += s[pos++];
}
}
return res;
}
void print_combinaison(const std::string& msg)
{
std::string s(msg.size(), '0');
s.resize(7, '1');
// s is a string of 7 letter with '0' (representing letter)
// and '1' representing '*'
// initial value of s is one of 0000000, 0000001, 0000011, 0000111,
// 0001111, 0011111, 0111111 or 1111111.
do
{
if (s.find("111") != std::string::npos) continue;
std::cout << convert(s, msg) << std::endl;
} while (std::next_permutation(begin(s), end(s)));
}
I am having issues with the following code and I cant figure out why out of loop is not being printed. With this code I want the program to ignore any spaces inputted by the user and after a space is inputted the number previously entered is stored in an array location. Like this I want 6 and 78 to be stored in 2 array locations not store them individually as 6 7 8.
This is my code:
while ((in=getchar()) != '0')
{
if (in == ' ')
{
printf("space\n ");
continue;
}
else
{
printf("assigning\n ");
input[i]=in;
}
i++;
}
printf("Out of Loop");
My output when inputting 5 6 78 is:
assigning
space
assigning
space
assigning
assigning
assigning
With this output I doubt whether 78 is being stored in one memory location.
I would really appreciate your help,Thankyou
C++:
std::vector<int> v;
std::string s;
int i;
std::getline( std::cin, s); // read full line with whitespaces
std::istringstream iss( s); // prepare to process the line
while( iss >> i) v.push_back( i); // read into i and push into vector if
// operator>> was successful
C:
int array[ 10];
int i = 0, retval;
while( i < 10 && ( retval = scanf( "%d", &array[ i++])) == 1) ;
if( i == 10) {
// array full
}
if( retval == 0) {
// read value not an integer. matching failure
}
if( retval == EOF) {
// end of file reached or a read error occurred
}
You are deciding character by character. Thus, you will only store single digits or ignore those digits.
You could store the whole numbers like this (extending your code):
bool currentNumberStarted = false;
int currentNumber = 0;
int idx = 0;
while ((in=getchar()) != '0')// you probably want '\0' instead of '0'
{
if (in == ' ')
{
if (currentNumberStarted)
{
input[idx]=currentNumber;
idx++;
currentNumberStarted = false;
}
printf("space\n ");
continue;
}
else
{
printf("assigning\n ");
currentNumberStarted = true;
currentNumber *= 10;
currentNumber += in;
}
}
printf("Out of Loop");
First of all I highly doubt that your while loop will ever end, even if you made that to '\0' ,Because you are using char variable to store input. Not strings, Only strings uses '\0' at the end,How can we enter '\0' from keyboard..???. even if you want to keep it as '0',you would alwasy have to enter 0 as last number to end the loop(which i think you dont want to.)
So the Solution is this:-
After Entering Numbers You will Hit ENTER key, which would generate a newline character '\n' so you have to check for new line character('\n'), And as you are using getchar() function, it will returns EOF (-1) at the end of input, so its important to check for it too.So you have to check for both '\n' and EOF at once in while loop.And at last you should also check for array index number(it should be less than 1) in which you are storing numbers.
I made some effort to make you understand the program in comments.
int main()
{
int i=0;
int input[10]={0}; //here only 10 integers can be entered(hence i should be i<10)
int in; //To store input character
int num=0; //To store number which is converted from character.
int new=1; //To check if new number is started 0=false 1=True.
int count=0;//This is just to know how many numbers entered,also used to print numbers at end.
while ((in=getchar()) != '\n' && (in!=EOF) && i<10)//should check for both '\n' and EOF and array index also
{
if (in == ' ')
{
printf("space\n ");
if(new==0) //if new Number is not started yet.
{
new=1; //Start of a New number.(a number entered after space)
i++; //As new number is started it should be stored in new array index.
}
continue; //if space is entered just go to begining
}
else
{
printf("assigning\n ");
num=in-48; //converts a character to number (ex:- converts '3' to 3)
input[i]=(input[i]*10)+num; //storing the number..This is important do a paper work to understand this step.
new=0; //still in same number(we are still processing same number)
}
}
printf("Out of Loop \n");
count=i+1; //This gives correct count of numbers entered
for(i=0;i<count;i++) //to print numbers.
printf("%d ",input[i]);
return 0;
}
OUTPUT:-
E:>example.exe
78 2 65 998 1
assigning
assigning
space
assigning
space
.
.
.
space
assigning
Out of Loop
78 2 65 998 1