I am having some issues trying to get my code to work. It prints ALMOST the right data but maybe it isn't looping correctly? I don't think it repeats the key through the alphabet. It's all lowercase and doesn't exceed 26.
void vigenereEncrypt( const char plaintext[], char ciphertext[], const char key[] )
{
int idx;
int j;
for( idx = 0, j = 0; idx <= strlen(plaintext); idx++ )
{
if ( CHAR_OUT_OF_RANGE(plaintext[idx]) )
{
ciphertext[idx] = plaintext[idx];
}
else
{
ciphertext[idx] = plaintext[idx];
ciphertext[idx] += key[j] - MIN_ASCII_VALUE;
if (ciphertext[idx] >= MAX_ASCII_VALUE) ciphertext[idx] += -MAX_ASCII_VALUE + MIN_ASCII_VALUE - 1;
}
j = (j + 1) % strlen(key);
}
ciphertext[idx] = 0;
}
for instance: if I enter the plaintext toner with a key of jerry the output will be csevé. It should change it to csevp
Do everybody (especially yourself) a favor, and use std::string instead of C-style strings. Then use a standard algorithm instead of writing messing up the loops on your own.
#include <iostream>
#include <iterator>
#include <algorithm>
class crypt {
std::string key;
size_t pos;
public:
crypt(std::string const &k) : key(k), pos(0) { }
char operator()(char input) {
char ret = input ^ key[pos];
pos = (pos + 1) % key.size();
return ret;
}
};
int main() {
std::string input("This is some input to be encrypted by the crappy encryption algorithm.");
std::transform(input.begin(), input.end(),
std::ostream_iterator<char>(std::cout),
crypt("This is the key"));
return 0;
}
Your loop is going one-to-far. You should use < instead of <=. And I assume you should be testing for > MAX_ASCII_VALUE, not >= (but you haven't shown what MAX_ASCII_VALUE is).
But your basic problem is a signed vs. unsigned char problem. With signed chars, when it goes above 127 it wraps around and becomes negative, so the > test will fail when it should have passed.
void vigenereEncrypt(const char plaintext[], char ciphertext[], const char key[])
{
size_t i, j;
for(i = 0, j = 0; i < strlen(plaintext); ++i )
{
ciphertext[i] = plaintext[i];
if (!CHAR_OUT_OF_RANGE(plaintext[i]))
{
ciphertext[i] += (uchar)key[j] - (uchar)MIN_ASCII_VALUE;
if ((uchar)ciphertext[i] > (uchar)MAX_ASCII_VALUE)
ciphertext[i] -= (uchar)MAX_ASCII_VALUE - (uchar)MIN_ASCII_VALUE + 1;
}
j = (j + 1) % strlen(key);
}
ciphertext[i] = 0;
}
Related
Given a string S (that can contain multiple words), you need to find the word which has minimum length.
Note : If multiple words are of same length, then answer will be first minimum length word in the string.
Words are separated by single space only.
Input Format :
String S
Output Format :
Minimum length word
Constraints :
1 <= Length of String S <= 10^5
Sample Input 1 :
this is test string
Sample Output 1 :
is
Sample Input 2 :
abc de ghihjk a uvw h j
Sample Output 2 :
a
Please check what is wrong. There is nothing coming in the output.
Here is the code:
/* input - Input String
* output - Save the result in the output array (passed as argument). You don’t have to
* print or return the result
*/
int length(char input[], int si, int ei){
int len = 0;
for(int i = si; i <= ei; i++){
len++;
}
return len;
}
char getString(char input[], int index){
return input[index];
}
void minLengthWord(char input[], char output[]){
int prev = -1;
int i = 0;
int minLength = 0, len = 0;
int si, ei;
for(; input[i] != '\0'; i++){
if(input[i] == ' '){
int len = length(input, prev + 1, i - 1);
if(len > minLength){
minLength = len;
si = prev + 1;
ei = i - 1;
}
prev = i;
}
}
length(input, prev + 1, i - 1);
if(len > minLength){
minLength = len;
si = prev + 1;
ei = i - 1;
}
for(int i = 0; i < minLength; i++){
output[i] = getString(input, si + i);
}
// Write your code here
}
In fact it is an assignment on testing the knowledge of standard C string functions.
The code shown in the question does not make sense.
For example within the function length
int length(char input[], int si, int ei){
int len = 0;
for(int i = si; i <= ei; i++){
len++;
}
return len;
}
the parameter input is not used. The loop within the function is redundant. The function could be defined simpler like
int length( int si, int ei )
{
return ei - si + 1;
}
Or in the function minLengthWord this if statement
if(len > minLength){
minLength = len;
determines the maximum length of the word instead of the minimum length.
The best approach to define the function is to define it such a way when it returns the position and the length of the minimum word in the given string. Having such an information you always can easily extract the minimum word if it will be required.
Here is a demonstrative program.
#include <iostream>
#include <utility>
#include <cstring>
std::pair<size_t, size_t> minimum_word( const char *s, const char *delim = " \t" )
{
std::pair<size_t, size_t> min = { 0, 0 };
size_t i = 0;
while ( *( s + i ) )
{
i += std::strspn( s + i, delim );
if ( *( s + i ) )
{
size_t n = std::strcspn( s + i, delim );
if ( min.second == 0 || n < min.second )
{
min.first = i;
min.second = n;
}
i += n;
}
}
if ( min.second == 0 ) min.first = i;
return min;
}
int main()
{
const char *s = "Hello John Bradely";
auto min = minimum_word( s );
std::cout << "The minimum word is ";
std::cout.write( s + min.first, min.second ) << '\n';
return 0;
}
The program output is
The minimum word is John
It is easy to change the shown function such a way that it will return a dynamically created array where the minimum word will be copied.
#include <iostream>
#include <utility>
#include <cstring>
char * minimum_word( const char *s, const char *delim = " \t" )
{
std::pair<size_t, size_t> min = { 0, 0 };
size_t i = 0;
while ( *( s + i ) )
{
i += std::strspn( s + i, delim );
if ( *( s + i ) )
{
size_t n = std::strcspn( s + i, delim );
if ( min.second == 0 || n < min.second )
{
min.first = i;
min.second = n;
}
i += n;
}
}
if ( min.second == 0 ) min.first = i;
char *word = new char[min.second + 1]();
std::memcpy( word, s + min.first, min.second );
return word;
}
int main()
{
const char *s = "Hello John Bradely";
char *word = minimum_word( s );
std::cout << "The minimum word is " << word << '\n';
delete [] word;
return 0;
}
The program output is
The minimum word is John
#include<bits/stdc++.h>
#include<iostream>
using namespace std;
void minLengthWord(char input[], char output[]){
int n=strlen(input);
int mini=INT_MAX;
int start=-1;
int cnt=0;
for(int i=0;i<=n;i++){
if(input[i]!=' ' && i!=n){
cnt++;
}
else if(cnt<mini||(i==n &&cnt<mini)){
mini=cnt;
start=i-mini;
cnt=0;
}
else{
cnt=0;
}
}
for(int i=0;i<mini;i++){
output[i]=input[i+start];
}
}
int main(){
char ch[10000], output[10000];
cin.getline(ch, 10000);
minLengthWord(ch, output);
cout << output << endl;
}
I'm pretty new to C++ and am very confused as to what is happening here. The error is the line int len = strlen(strin);. Any suggestions how to fix this would be much appreciated.
BigNum::BigNum(const std::string& strin)
{
digits = NULL;
int len = strlen(strin);
if (len == 0)
{
BigNum zero;
*this = zero;
return;
}
used = len;
positive = true;
int i = 0;
if(strin[i] == '-')
{
positive = false;
i = 1;
used--;
}
else if(strin[i] == '+')
{
i = 1;
used--;
}
capacity = double_up_default(used);
digits = new unsigned int[capacity];
for(unsigned int k = 0; k < used; ++k)
{
digits[used - k - 1] = strin[i++] - '0';
}
trim();
}
strlen knows nothing about std::string. It is a C function that returns the length of a null-terminated string.
Fortunately std::string knows its own length. Try this instead:
int len = strin.size();
or, if you care about the range of sizes a string may have,
std::string::size_type len = strin.size();
Some guy presented me with a beautiful code in my other question. Here it is:
#include <iostream>
#include <cstring>
using namespace std;
void encode(char* source, char const* alpha)
{
int i, j;
int len = strlen(source);
for (i = 0; i < len; i++)
{
if (source[i] >= 'a' && source[i] <= 'z')
{
j = source[i] - 'a';
source[i] = alpha[j];
}
}
}
int main(void)
{
char source[1001];
char alpha[27];
cin.getline(source, 1001);
cin.getline(alpha, 27);
encode(source, alpha);
cout << source;
return 0;
}
What should I do to transform this void function into a char* one (it should become char* encode(char* source, char const* alpha))? Apparently as it won't be a 'void' it should return a value but what value? Those pointers confuse me immensely.
#include <iostream>
#include <cstring>
using namespace std;
char* encode(char* source, char const* alpha)
{
int i, j;
int len = strlen(source);
for (i = 0; i < len; i++)
{
if (source[i] >= 'a' && source[i] <= 'z')
{
j = source[i] - 'a';
source[i] = alpha[j];
}
}
return source;
}
int main()
{
char source[1001];
char alpha[27];
cin.getline(source, 1001);
cin.getline(alpha, 27);
cout << encode(source, alpha);
return 0;
}
Do something like that. And if you want to change a char array of main, your void function would work. :)
char* encode(char* source, char const* alpha)
{
int i, j;
int len = strlen(source);
for (i = 0; i < len; i++)
{
if (source[i] >= 'a' && source[i] <= 'z')
{
j = source[i] - 'a';
source[i] = alpha[j];
}
}
return source;
}
Though it doesn't look like your doing anything with that return value.
(Were you supposed to return a copy of the char array, or is modifying in-place it okay?)
Returning char * really only makes sense if you're trying to alert the calling function an error has occurred:
char *encode(char *source, char const *alpha)
{
int i, j;
int len = strlen(source);
/* Check For Argument Errors */
if((source == NULL) || (alpha == NULL))
return NULL;
for (i = 0; i < len; i++)
{
if (source[i] >= 'a' && source[i] <= 'z')
{
j = source[i] - 'a';
source[i] = alpha[j];
}
}
return source;
}
The calling function can check for errors like this:
if(encode(source, alpha) == NULL)
{
printf("Encoding error!\n");
return -1;
}
else
{
cout << source;
}
I have a string like str="ABCDEFGHIJK";
need o/p like this str="CBAFEDIHGJK"
am getting "CBA" correctly after that its not printing anything.
can anyone check the following code and let me know where is the problem?
int main()
{
string str="ABCDEFGHIJK";
char str1[10],rev[10];
int n=str.length(),count=0,c=3,k=0,j=0;
for(int i=0;i<n;i++)
{
str1[i]=str[i];
count++;
cout<<str1[i]<<" and "<<count<<"and "<<c<<endl;
if(count==c)
{
cout<<"Entered into if loop"<<count<<"and"<<c<<"and "<<k<<endl;
cout<<c<<" and "<<k<<endl;
while(j<c)
{
rev[j]=str1[c-k-1];
cout<<rev[j]<<" and "<<str1[c-k-1]<<endl;
j++;
k++;
}
count=0;
}
/*else
{
if(count < c && str[i]=='\0')
{
for(int k=0;k<count;k++)
{
rev[k]=str1[count-1];
count--;
count=0;
}
}
}*/
}
cout<<"The string is: "<<rev<<endl;
return 0;
}
Please help me on this.
No need to use a c++ string object for this use-case; just use a normal char *.
Also, always make sure you store enough room for the string null-terminator character ('\0'). This is required as c string functions assume your string is terminated in this way.
Following will reverse string in ansi C89
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void reverse(char *in, char *rev)
{
int i, n;
n = strlen(in);
for(i = n-1; i>=0; i--)
{
rev[n-i-1] = in[i];
}
/* add the null-terminator */
rev[n] = '\0';
}
int main()
{
char *str = "ABCDEFGHIJK";
char str1[12], temp;
char triplet[4];
char rev_triplet[4];
int index;
triplet[3] = '\0';
rev_triplet[3] = '\0';
str1[0] = '\0';
for(index = 0; index < strlen(str); index += 3)
{
memcpy(triplet, str + index, 3 * sizeof(char));
reverse(triplet, rev_triplet);
strcat(str1, rev_triplet);
}
printf("Initial string is: %s\n", str);
printf("Reverse string is: %s\n", str1);
return 0;
}
Outputs
$ ./test
Initial string is: ABCDEFGHIJK
Reverse string is: CBAFEDIHGKJ
If you intend to use C++ (and not C) for this:
#include <algorithm>
#include <iostream>
#include <string>
std::string reverse_triples(std::string s)
{
const unsigned int N = 3;
for (int i = 0, j = N - 1; i < s.length() - (s.length() % N); i += N, j += N)
{
std::swap(s[i], s[j]);
}
return s;
}
int main()
{
std::string s = "ABCDEFGHIJK";
std::string rs = reverse_triples(s);
std::cout << "Reversed Triples: " << rs << std::endl;
return 0;
}
Whatever value of N you need can be modified (and even supplied as a function parameter if you want). You only need to swap the outer characters (so all the elements below N / 2 will be swapped with the elements above N / 2). For N == 3, it is just a single swap. If you want to do it more generically:
#include <algorithm>
#include <iostream>
#include <string>
std::string reverse_substrings(std::string s, unsigned int substring_size)
{
for (int i = 0, j = substring_size - 1; i < s.length() - (s.length() % substring_size); i += substring_size, j += substring_size)
{
std::reverse(s.begin() + i, s.begin() + j + 1);
}
return s;
}
int main()
{
std::string s = "ABCDEFGHIJK";
std::string rs = reverse_triples(s, 4); // passing 3 gets you the same results as before
std::cout << "Reversed Triples: " << rs << std::endl;
return 0;
}
First, let us examine how std::reverse might be implemented. It uses iterators.
template <class BidirectionalIterator>
void reverse (BidirectionalIterator first, BidirectionalIterator last)
{
while ((first!=last)&&(first!=--last)) {
std::iter_swap (first,last);
++first;
}
}
We can extend the logic to use indices instead of iterators, where i and j represent iterators (positions) and s[i] and s[j] represent the data pointed to by the iterators.
void reverse(std::string& s)
{
int i = 0;
int j = s.size();
while ((i != j) && (i != (--j)))
{
std::swap(s[i], s[j]);
++i;
}
}
Now you want to reverse "chunks" rather than the entire string.
void reverse(int n, std::string& s)
{
int beg = 0;
int end = beg + n;
int size = s.size();
// We're going to modify s in place
// So store a copy
std::string copy = s;
s = "";
// Add + 1 to avoid the loop cutting off short
// Or do i <= size / n;
for (int i = 0; i < size / n + 1; i++)
{
std::string chunk(copy.begin() + beg, copy.begin() + end);
// If there's no n sized chunks left
// don't reverse
if (end < size)
reverse(chunk);
s += chunk;
beg += n;
// Don't go past the size of the string
end += (end + n > size ? size - end : n);
}
}
int main()
{
std::string s("ABCDEFGHIJK");
std::string target("CBAFEDIHGJK");
reverse(3, s);
std::cout << s << "|" << target <<"|\n";
std::cout << s.size() << " " << target.size() << "\n"; // 11 11
std::cout << std::boolalpha << (s == target); // true
return 0;
}
i was looking around the forums and i still couldnt find my answer to my problem.
I got two strings, that are just really an array of numbers. for example(i just choose random numbers
string input1="12345678909876543212";
string input2="12345";
I want to add these two string together but act them like there integers.
My goal is creating a class where i can add bigger numbers than (long long int) so it can exceed the largest long long int variable.
So i revese the string with no problem, so now there
input1="21234567890987654321"
input2="54321"
then i tried adding, let's say input1[0]+input2[0] (2+5) to a new string lets call it newString[0] where that would equal (7); but i cant find a good way to temporally convert the current number in the string so i can add it to the new string? can anyone help. I get sick and tired of atoi,stof,stod. they don't seem to work at all for me.
Any way i can make this function work.
I don't care about making the class yet, i just care about finding a way to add those two strings mathematically but still maintaining the newString's string format. Thank you for whoever can figure this out for me
Okay, so, assuming your only problem is with the logic, not the class design thing, I came up with this logic
fill up the inputs with 0s, checking the lengths, match the lengths
add like normal addition, keeping track of carry
finally remove leading zeros from result
So using std::transform with a lambda function on reverse iterators :-
char carry = 0;
std::transform(input1.rbegin(),input1.rend(),input2.rbegin(),
result.rbegin(),[&carry]( char x, char y){
char z = (x-'0')+(y-'0') + carry;
if (z > 9)
{
carry = 1;
z -= 10;
}
else
{
carry = 0;
}
return z + '0';
});
//And finally the last carry
result[0] = carry + '0';
//Remove the leading zero
n = result.find_first_not_of("0");
if (n != string::npos)
{
result = result.substr(n);
}
See Here
Edit "Can you comment on what your doing here"
+--------+--------------+------------+-------> Reverse Iterator
| | | |
std::transform( | input1.rbegin(), input1.rend(),input2.rbegin(),
result.rbegin(), [&carry]( char x, char y){
//This starts a lambda function
char z = (x-'0')+(y-'0') + carry; // x,y have ASCII value of each digit
// Substracr ASCII of 0 i.e. 48 to get the "original" number
// Add them up
if (z > 9) //If result greater than 9, you have a carry
{
carry = 1; // store carry for proceeding sums
z -= 10; // Obviously
}
else
{
carry = 0; //Else no carry was generated
}
return z + '0'; // Now you have "correct" number, make it a char, add 48
});
std::transform is present in header <algorithm>, see the ideone posted link.
Here's A Solution for adding two numbers represented as strings .
#include<iostream>
using namespace std;
string add(string a, string b)
{
int al=a.size()-1;
int bl=b.size()-1;
int carry=0;
string result="";
while(al>=0 && bl>=0)
{
int temp = (int)(a[al] - '0') + (int)(b[bl] - '0') + carry ;
carry = 0;
if(temp > 9 )
{
carry=1;
temp=temp-10;
}
result+=char(temp + '0');
al--;
bl--;
}
while(al>=0)
{
int temp = (int)(a[al] - '0') + carry ;
carry = 0;
if(temp>9)
{
carry=1;
temp=temp%10;
}
result+=char(temp + '0');
al--;
}
while(bl>=0)
{
int temp = (int)(b[bl] - '0') + carry ;
carry = 0;
if(temp>9)
{
carry=1;
temp=temp%10;
}
result+=char(temp + '0');
bl--;
}
if(carry)
result+="1";
string addition="";
for(int i=result.size()-1;i>=0;i--)
addition+=result[i]; // reversing the answer
return addition;
}
string trim(string a) // for removing leading 0s
{
string res="";
int i=0;
while(a[i]=='0')
i++;
for(;i<a.size();i++)
res+=a[i];
return res;
}
int main()
{
string a;
string b;
cin>>a>>b;
cout<<trim(add(a,b))<<endl;
}
I am not a very femilier with C++ but cant we do this?
int i = stoi( input1[0]);
int j = stoi( input2[0]);
int x = i+j;
Please note this can be done in C++11 Please refer [1] and 2 as well
You can convert a char to an int by subtracting '0' from it:
char sumdigit = (input1[0]-'0') + (input2[0]-'0') + '0';
atoi() would be a better to go, as far as converting input[0] to an int:
int temp = atoi(input.substr(0,1).c_str());
then use stringstream to convert back to string:
stringstream convert;
convert << temp;
string newString = convert.str();
Here is a solution, but this is so far from sensible that it is not even funny.
GCC 4.7.3: g++ -Wall -Wextra -std=c++0x dumb-big-num.cpp
#include <algorithm>
#include <cctype>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
// dumb big num
// unsigned integer
class DBN {
public:
DBN() : num("0") {}
explicit DBN(const std::string& s) : num(s) {
for (const auto& c : num) {
if (!std::isdigit(c)) { throw std::invalid_argument("DBN::DBN"); } }
std::reverse(std::begin(num), std::end(num)); }
DBN operator+(const DBN& rhs) const {
DBN tmp(*this);
return tmp += rhs; }
DBN& operator+=(const DBN& rhs) {
std::string r;
const int m = std::min(num.size(), rhs.num.size());
int c = 0;
for (int i = 0; i < m; ++i) {
int s = (num[i] - '0') + (rhs.num[i] - '0') + c;
c = s / 10;
s %= 10;
r += static_cast<char>('0' + s); }
const std::string& ref = num.size() < rhs.num.size() ? rhs.num : num;
for (int i = m; i < ref.size(); ++i) {
int s = (ref[i] - '0') + c;
c = s / 10;
s %= 10;
r += static_cast<char>('0' + s); }
if (0 < c) { r += '1'; }
num = r;
return *this; }
friend std::ostream& operator<<(std::ostream& os, const DBN& rhs);
friend std::istream& operator>>(std::istream& os, DBN& rhs);
private:
std::string num;
};
std::ostream& operator<<(std::ostream& os, const DBN& rhs) {
std::string s(rhs.num);
std::reverse(std::begin(s), std::end(s));
return os << s;
}
std::istream& operator>>(std::istream& is, DBN& rhs) {
std::stringstream ss;
char c;
while (is && std::isspace(is.peek())) { is.ignore(); }
while (is) {
if (!std::isdigit(is.peek())) { break; }
is >> c;
ss << c; }
DBN n(ss.str());
rhs = n;
return is;
}
int main() {
DBN a, b, t;
while (std::cin >> a >> b) {
std::cout << a + b << "\n";
(t += a) += b;
}
std::cout << t << "\n";
}
Here it is a simple C++ code
string Sum(string a, string b)
{
if(a.size() < b.size())
swap(a, b);
int j = a.size()-1;
for(int i=b.size()-1; i>=0; i--, j--)
a[j]+=(b[i]-'0');
for(int i=a.size()-1; i>0; i--)
if(a[i] > '9')
{
int d = a[i]-'0';
a[i-1] = ((a[i-1]-'0') + d/10) + '0';
a[i] = (d%10)+'0';
}
if(a[0] > '9')
{
string k;
k+=a[0];
a[0] = ((a[0]-'0')%10)+'0';
k[0] = ((k[0]-'0')/10)+'0';
a = k+a;
}
return a;
}
cited from C - Adding the numbers in 2 strings together if a different length
answer, I write a more readable code:
void str_reverse(char *beg, char *end){
if(!beg || !end)return;
char cTmp;
while(beg < end){
cTmp = *beg;
*beg++ = *end;
*end-- = cTmp;
}
}
#define c2d(c) (c - '0')
#define d2c(d) (d + '0')
void str_add(const char* s1, const char* s2, char* s_ret){
int s1_len = strlen(s1);
int s2_len = strlen(s2);
int max_len = s1_len;
int min_len = s2_len;
const char *ps_max = s1;
const char *ps_min = s2;
if(s2_len > s1_len){
ps_min = s1;min_len = s1_len;
ps_max = s2;max_len = s2_len;
}
int carry = 0;
int i, j = 0;
for (i = max_len - 1; i >= 0; --i) {
// this wrong-prone
int idx = (i - max_len + min_len) >=0 ? (i - max_len + min_len) : -1;
int sum = c2d(ps_max[i]) + (idx >=0 ? c2d(ps_min[idx]) : 0) + carry;
carry = sum / 10;
sum = sum % 10;
s_ret[j++] = d2c(sum);
}
if(carry)s_ret[j] = '1';
str_reverse(s_ret, s_ret + strlen(s_ret) - 1);
}
test code as below:
void test_str_str_add(){
char s1[] = "123";
char s2[] = "456";
char s3[10] = {'\0'};
str_add(s1, s2, s3);
std::cout<<s3<<std::endl;
char s4[] = "456789";
char s5[10] = {'\0'};
str_add(s1, s4, s5);
std::cout<<s5<<std::endl;
char s7[] = "99999";
char s8[] = "21";
char s9[10] = {'\0'};
str_add(s7, s8, s9);
std::cout<<s9<<std::endl;
}
output:
579
456912
100020