It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
Well, I have to make a task, that will sort elements of array in UNIQUE way.
So, for example, if I input 1st string:
BOB, I have to do: 2+15+2 (because of their positioning in the alphabet) and then divide by amount of chars /3 and do that for all inputted strings and then sort them by highest to lowest. :)
My question is, how do I set value 1,2,3,4,5... for A,B,C,D,E..... (only big letters).
Thank you.
If the underlying encoding is seuqential, such as ascii.
letter - 'A' + 1
A more robust and general approach, would be to examine the char_traits of the character type.
You need to define a function
int weight(const std::string& s);
And then iterate on the string char by char and do following:
w = ch - 'A' + 1
You also may check that the char is before 'A' and 'Z' or assume that.
You need to read more about ASCII
EDIT:
Code of weight function (simplified):
int weight(const std::string& s) {
int sum = 0, i = 0;
for(i = 0; i < s.size(); i++) {
char ch = s[i];
sum += ch - 'A' + 1;
}
return sum/i;
}
If you are working on an ASCII machine, #StoryTeller's answer works. Otherwise you can create an array to map between the two:
const char letters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static const int numbers [ 256 ] = { 0 };
for ( size_t index = 0; index < sizeof letters; ++index ) {
numbers [ letters [ index ] ] = index + 1;
}
assert ( numbers [ 'A' ] == 1 )
assert ( numbers [ 'Z' ] == 26 )
To get the values you could use the following code:
int getValue(char which)
{
int ret = 0;
switch(which)
{
case 'a' : ret = 1 ; break;
case 'A' : ret = 27 ; break;
case 'b' : ret = 2 ; break;
case 'B' : ret = 28 ; break;
// and so on....
}
return ret;
}
int result = 0;
while(....)
{
result = result + getValue(myarray[counter]);
}
You only need to escape the string to array and loop through it...
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
How can I generate all combinations of n elements in groups of k?
For example, takig "abcd" in groups of 3, from [aaa] to [ddd]?
EDIT: What I've "accomplished" so far:
int main (int argc, char * argvc[]) {
int tComb = 0, array[7] = { 48 , 48 , 48 , 48 , 48 , 48 , 48 };
while ( tComb < atoi(argvc[1]) ) {
for (int i = 6 ; i>0 ; i--) {
if (array[i] == 58)
array[i] = 65;
if (array[i] == 91)
array[i] = 97;
if (array[i] == 123){
array[i] = 48;
array[i-1]++;
}
}
std::cout << "Current Combination: ";
std::cout << array;
std::cout << "\n";
tComb++;
array[6]++;
}
}
It'll try and generate backward the latest combination of alphanumeric characters, but it's hardcoded and won't work well.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
unsigned powu(unsigned base, unsigned exp){
unsigned result = 1;
while(exp > 0){
if(exp & 1)
result *= base;
base = base * base;
exp >>=1;
}
return result;
}
int main(int argc, char *argv[]){
if(argc != 3){
fprintf(stderr, "Usage : RepeatedPermutation abcd 3\n");
return -1;
}
char *list = argv[1];
unsigned gp_len = atoi(argv[2]);
unsigned list_len = strlen(list);
char *gp = calloc(gp_len+1, sizeof(char));
int total_n = powu(list_len, gp_len);
int i, j;
for(i=0;i<total_n;++i){
int n = i;
for(j=0;j<gp_len;++j){
gp[gp_len -j -1] = list[n % list_len];
n /= list_len;
}
printf("[%s]\n", gp);
}
free(gp);
return 0;
}
Am not sure but i think this is the answer to your question. If you want three groups than you should have 3 different loops.Its pretty simple when you see the output of this program.
You just need to increment the value of what ever you want to generate there possible combination.
The below Code will generate all possible combination of "abcd" in groups of 3, from [aaa] to [ddd].
int main()
{
char ch1;
char ch2;
char ch3;
for(ch1='a';ch1<='d';ch1++)
{
for(ch2='a';ch2<='d';ch2++)
{
for(ch3='a';ch3<='d';ch3++)
{
printf("%c %c %c\n",ch1,ch2,ch3);
}
printf("\n"); //just to have clean and understandable output
}
printf("\n\n\n"); //just to have clean and understandable output
}
return 0;
}
One method to generate all the combinations is to treat this as a number counting program.
The Counting Algorithm
Let's take the case of "digits": a, b, c, and d.
The first number is: aaaa. Much like decimal: 0000.
The second number is: aaab. Decimal: 0001.
The third number is: aaac, decimal: 0002.
The fourth number is: aaad, decimal: 0003.
This process is known as incrementing, e.g. adding a constant value each time.
Now comes the tricky part, incrementing the last digit. According to number counting rules, when the last digit is reached, the last digit is replaced by the first and the digit in the next column is replaced. This is equivalent of a decimal number incrementing from 09 to 10.
So in the example above, the next number in the sequence is: aaba.
This is known as carry, as you are carrying the overflow to the next digit.
Converting Algorithm to Code
Looks like there is a loop to count from first digit to last digit:
#define MAXIMUM_DIGIT_POSITIONS 4
const char FIRST_CHAR = 'a';
const char LAST_CHAR = 'd';
std::vector<char> number(MAXIMUM_DIGIT_POSITIONS); // Reserve some slots.
void Print_Number(const std::vector<char>& number);
int main(void)
{
// Initialize the number
int position = 0;
for (position = 0; position < MAXIMUM_DIGIT_POSITIONS; ++position)
{
number.push_back(FIRST_CHAR);
}
Print_Number(number);
// Loop: incrementing
position = MAXIMUM_DIGIT_POSITIONS - 1; // Because arrays are zero based indexing
while (number[position] < LAST_CHAR)
{
number[position] = number[position] + 1; // Increment to next digit, same position.
Print_Number(number);
}
// Pause before closing
std::cout << "Paused. Press ENTER to close.\n";
std::cin.ignore(100000, '\n');
return EXIT_SUCCESS;
}
void Print_Number(const std::vector<char>& number)
{
for (std::vector<char>::const_iter iter = number.begin();
iter != number.end();
++iter)
{
std::cout << *iter;
}
cout << "\n";
}
Handling Carry
The above program demonstrates counting in a single column. But how to handle the incrementing of the last digit?
Looks like we need to increment the digit in the previous position.
Looking ahead, the value in the previous column will be incremented, until it too, needs to be increment. Thus the carry will be propagate to the previous column. Looks like another loop:
// Loop: number of positions
int propagation_position = position - 1;
while (propagation_position >= 0)
{
while (number[position] < LAST_CHAR)
{
number[position] = number[position] + 1; // Increment to next digit, same position.
Print_Number(number);
}
// Propagate the carry.
while (propagation_position >= 0)
{
if (number[propagation_position] != LAST_CHAR)
{
++number[propagation_position];
number[propagation_position + 1] = FIRST_CHAR;
break;
}
--propagation_position;
}
position = 0;
}
The above new fragment has an outer while loop and a second inner while loop. The outer while loop controls the digit position. The second inner while loop handles the carry.
The whole program is designed so that you can adjust the number of digit positions and the number of digits in the sequence.
Summary
The brute force method for printing all the combinations is like counting numbers. The same principles apply: when the last digit is incremented, it is replaced by the first digit and the digit of the next column is incremented. This is repeated until all positions have been counted.
Walk through the above code with debugger or pen and paper to find any defects and understand the algorithm.
After you understand the algorithm, search your favorite C++ reference for "c++ combination permutation algorithm".
Below is an example code that is not working the way I want.
#include <iostream>
using namespace std;
int main()
{
char testArray[] = "1 test";
int numReplace = 2;
testArray[0] = (int)numReplace;
cout<< testArray<<endl; //output is "? test" I wanted it 2, not a '?' there
//I was trying different things and hoping (int) helped
testArray[0] = '2';
cout<<testArray<<endl;//"2 test" which is what I want, but it was hardcoded in
//Is there a way to do it based on a variable?
return 0;
}
In a string with characters and integers, how do you go about replacing numbers? And when implementing this, is it different between doing it in C and C++?
If numReplace will be in range [0,9] you can do :-
testArray[0] = numReplace + '0';
If numReplace is outside [0,9] you need to
a) convert numReplace into string equivalent
b) code a function to replace a part of string by another evaluated in (a)
Ref: Best way to replace a part of string by another in c and other relevant post on SO
Also, since this is C++ code, you might consider using std::string, here replacement, number to string conversion, etc are much simpler.
You should look over the ASCII table over here: http://www.asciitable.com/
It's very comfortable - always look on the Decimal column for the ASCII value you're using.
In the line: TestArray[0] = (int)numreplace; You've actually put in the first spot the character with the decimal ASCII value of 2. numReplace + '0' could do the trick :)
About the C/C++ question, it is the same in both and about the characters and integers...
You should look for your number start and ending.
You should make a loop that'll look like this:
int temp = 0, numberLen, i, j, isOk = 1, isOk2 = 1, from, to, num;
char str[] = "asd 12983 asd";//will be added 1 to.
char *nstr;
for(i = 0 ; i < strlen(str) && isOk ; i++)
{
if(str[i] >= '0' && str[i] <= '9')
{
from = i;
for(j = i ; j < strlen(str) && isOk2)
{
if(str[j] < '0' || str[j] > '9')//not a number;
{
to=j-1;
isOk2 = 0;
}
}
isOk = 0; //for the loop to stop.
}
}
numberLen = to-from+1;
nstr = malloc(sizeof(char)*numberLen);//creating a string with the length of the number.
for(i = from ; i <= to ; i++)
{
nstr[i-from] = str[i];
}
/*nstr now contains the number*/
num = atoi(numstr);
num++; //adding - we wanted to have the number+1 in string.
itoa(num, nstr, 10);//putting num into nstr
for(i = from ; i <= to ; i++)
{
str[i] = nstr[i-from];
}
/*Now the string will contain "asd 12984 asd"*/
By the way, the most efficient way would probably be just looking for the last digit and add 1 to it's value (ASCII again) as the numbers in ASCII are following each other - '0'=48, '1'=49 and so on. But I just showed you how to treat them as numbers and work with them as integers and so. Hope it helped :)
This question already has answers here:
Counting the Frequency of Specific Words in Text File
(4 answers)
Closed 9 years ago.
I wrote a function for counting frequency of specific word in a text.This program every time return zero.How can I improve it?
while (fgets(sentence, sizeof sentence, cfPtr))
{
for(j=0;j<total4;j++)
{
frequency[j] = comparision(sentence,&w);
all_frequency+=frequency[j];
}}
.
.
.
int comparision(const char sentence[ ],char *w)
{
int length=0,count=0,l=0,i;
length= strlen(sentence);
l= strlen(w);
while(sentence[i]!= '\n')
if(strncmp(sentence,w,l))
count++;
i++;
return count;
}
I have proofread your code and have commented on coding style and variable names. There
is still a flaw I left with the conditional, which is due to not iterating through the
sentence.
Here is your code marked up:
while(fgets(sentence, sizeof sentence, cfPtr)) {
for(j=0;j<total4;j++){
frequency[j] = comparision(sentence,&w);
all_frequency+=frequency[j];
}
}
// int comparision(const char sentence[ ],char *w) w is a poor variable name in this case.
int comparison(const char sentence[ ], char *word) //word is a better name.
{
//int length=0,count=0,l=0,i;
//Each variable should get its own line.
//Also, i should be initialized and l is redundant.
//Here are properly initialized variables:
int length = 0;
int count = 0;
int i = 0;
//length= strlen(sentence); This is redundant, as you know that the line ends at '\n'
length = strlen(word); //l is replaced with length.
//while(sentence[i]!= '\n')
//The incrementor and the if statement should be stored inside of a block
//(Formal name for curley braces).
while(sentence[i] != '\n'){
if(strncmp(sentence, word, length) == 0) //strncmp returns 0 if equal, so you
count++; //should compare to 0 for equality
i++;
}
return count;
}
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I need to convert two integers into two arrays of digits, so for example 544 would become arr[0] = 5, arr[1] = 4, arr[2] = 4.
I have found some algorithms doing this, but they create new array, and return this. I would have to allocate this memory for two arrays, so I wanna pass two integers by reference and do this on them directly.
I guess I can do this, because these integers are in fact template types, so they should be changeable. That's why I added C++ tag here.
Just using something like this:
int n = 544; // your number (this value will Change so you might want a copy)
int i = 0; // the array index
char a[256]; // the array
while (n) { // loop till there's nothing left
a[i++] = n % 10; // assign the last digit
n /= 10; // "right shift" the number
}
Note that this will result in returning the numbers in reverse order. This can easily be changed by modifying the initial value of i as well as the increment/decrement based on how you'd like to determine to length of the value.
(Brett Hale) I hope the poster doesn't mind, but I thought I'd add a code snippet I use for this case, since it's not easy to correctly determine the number of decimal digits prior to conversion:
{
char *df = a, *dr = a + i - 1;
int j = i >> 1;
while (j--)
{
char di = *df, dj = *dr;
*df++ = dj, *dr-- = di; /* (exchange) */
}
}
A simple solution is:
int i = 12312278;
std::vector<int> digits;
while (i)
{
digits.push_back(i % 10);
i /= 10;
}
std::reverse(digits.begin(), digits.end());
or, string based ( i >= 0 )
for (auto x : to_string(i))
digits.push_back(x-'0');
Call the integer a.
To get the units digit of a, a % 10
To shift a down so the tens is the units digit, a / 10
To know when you're done, a == 0
To know how large your array needs to be in the first place, min(ceil(log(a+1, 10)), 1) (to convince yourself this works, try the logarithm part of it in a calculator. if you don't have multiple argument log, use the identity log(x,y) == log(x)/log(y))
You can do something like this if you are using C++:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main()
{
int a=544;
stringstream str;
str << a;
string arr;
str>>arr;
for(int i=0; i<arr.length(); i++)
{
cout << arr[i];
}
system("pause");
return 0;
}
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
I have a string "D", that I want to convert into the integer 4.
(Additional information from OP)
D should convert into a decimal value . I want it to be "4".
for D = "4" ; E = "5"; and so on...
It may have the combination . If AA comes ,the value should be 27 and ll increase consequetively.
It looks like this is what you want (based on your question and comments):
unsigned long long convert(string str)
{
unsigned long long result = 0;
for (int i = 0;i<str.length();i++)
result+= (str[i] - 'A' + 1) + i*26;
return result;
}
Now for "D" it will give 4, for "AA" it will give 1+26 = 27 and so on...
A one-character string isn't so hard:
const int fromBase26 = ('D' - 'A') + 1;
This will set fromBase26 to 4.
For n-digit base parsing the algorithm is something like:
set output to 0
while input digits to convert:
output *= base
output += least significant input digit
remove least significant input digit from input
Note that this reads digits from the right of the input.
char* str = "ABC";
int i, len, num, pos;
len = strlen(str);
num = 0;
pos = 1;
for (i = 0; i < len; i++) {
num += pos * ((str[i] - 'A') + 1);
pos *= 26;
}
num will contain the result.