Generate string that doesn't match one in set - c++

Sort of an odd question- how would I go about generating a character string that doesn't match any in a set of strings? I don't want to make any assumptions about the strings. Solution is ideally STL based, but doesn't have to be
Example:
vector<string> strings;
/*...*/
string unMatching = generateUnmatching(strings); //this is the function I want
assert(find(strings.begin(), strings.end(), unMatching) == strings.end());

One way is to use diagonalization:
Start with an empty string s.
Look at the first character of the first string in the set. Choose any character other than that one, and append it to s.
Look at the second character of the second string in the set. Choose any character other than that one, and append it to s.
Follow the same pattern, always looking at the ith character of the ith string and appending a different character to s.
When you've finished with the last string in the set, s will differ from every string in the set in at least one position.
Another method would be to copy the longest string in the set and append any character to the copy. This new string will be different from every string in the set.
There are all kinds of other ways to accomplish the same thing. Adding some constraints to the problem would help in selecting an algorithm that makes the most sense for your problem. For example, you might decide to generate the shortest string that doesn't match any string in the set, or one with the lowest lexigraphic sort value, or one with the smallest number of characters in common with the other strings, or...

If you really don't have any requirement about the result string, you could simply do:
string answer = "a";
while (find(strings.begin(), strings.end(), unMatching) != strings.end())
answer += "a";
Apparently it doesn't seem to be what you want.
Here's the optimized solution that helps you find the shortest possible answer in the least amount of time:
Build a trie with your character set.
Do a breadth-first search from the root node, the first encountered empty node would be the shortest answer.
The time complexity of the optimized implementation is O(number_of_characters_in_all_strings), while a simple implementation with vector loop and lookup would be O(number_of_strings*lenth_of_string).

You could use a uuid generator, like the one from boost:
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/uuid/uuid_generators.hpp>
int main()
{
using namespace boost::uuids;
random_generator gen;
uuid u = gen();
std::string s = to_string(u);
std::cout << s;
}

you can use a random number generator (an example below) I think the ascii printable characters start at 33 and end at 127 and from -1 to -95
#include <stdlib.h>
#include <stdio.h> //only for printf
#define RANDINT(r) ((int)(r * (float)random() /(float)RAND_MAX + 0.5))
#define OFFSETRANDINT(r,o) (RANDINT(r) + o)
#define RANDINTX2Y(x,y) (OFFSETRANDINT((y-x),x))
int main(){
srandom(time(NULL)); // important to call this first, but only once
printf("%d\n",RANDINT(2147483647)); //a random int between 0 and 2147483647
printf("%d\n",OFFSETRANDINT(10,10)); //starting # 10 with a range of 10 (10-20)
printf("%d\n",RANDINTX2Y(0,10)); //between 0 and 10
}
you may need to cast the int to (char) so that you can store it in a string
then you can use either strstr or strcasestr depending on whether case matters
just strcat each string onto the "haystack" if it returns ! TRUE
#include <string.h>
char *strstr(const char *haystack, const char *needle);
char *strcasestr(const char *haystack, const char *needle);

Related

C++ Atoi can't handle special characters

Im using this atoi to remove all letters from the string. But my string uses special characters as seen below, because of this my atoi exits with an error. What should I do to solve this?
#include <iostream>
#include <string>
using namespace std;
int main() {
std::string playerPickS = "Klöver 12"; // string with special characters
size_t i = 0;
for (; i < playerPickS.length(); i++) { if (isdigit(playerPickS[i])) break; }
playerPickS = playerPickS.substr(i, playerPickS.length() - i); // convert the remaining text to an integer
cout << atoi(playerPickS.c_str());
}
This is what I believe is the error. I only get this when using those special characters, thats why I think thats my problem.
char can be signed or unsigned, but isidigt without a locale overload expects a positive number (or EOF==-1). In your encoding 'ö' has a negative value. You can cast it to unsigned char first: is_digit(static_cast<unsigned char>(playerPickS[i])) or use the locale-aware variant.
atoi stops scanning when it finds something that's not a digit (roughly speaking). So, to get it to do what you want, you have to feed it something that at least starts with the string you want to convert.
From the documentation:
[atoi] Discards any whitespace characters until the first non-whitespace character is found, then takes as many characters as possible to form a valid integer number representation and converts them to an integer value. The valid integer value consists of the following parts:
(optional) plus or minus sign
numeric digits
So, now you know how atoi works, you can pre-process your string appropriately before passing it in. Good luck!
Edit: If your call to isdigit is failing to yield the desired result, the clue lies here:
The behavior is undefined if the value of ch is not representable as unsigned char and is not equal to EOF.
So you need to check for that yourself before you call it. Casting playerPickS[i] to an unsigned int will probably work.

Finding location of character in input2 from input1

Important note: string (C++ object) and any other library such as array or vectors that could store unlimited characters cannot be used.
For my question:
We are given input 1, which is a sentence of unlimited characters. eg. Life is Beautiful.
Input 2: character who's location we have to find using the reference point (the middle character in input 1 after it is sorted and repeating characters are deleted) taken as zero. eg. fee.
An example:
Input 1: Life is beautiful
Input 2: see
Output: 2, -2, -2
Explanation: So firstly, we remove any spaces from input 1 and make all lowercase, then sort it in ascending order after which we find the reference letter (For above example, it's 'i'). We remove the repeating characters and then finally, put positions to character in input 1.
Example 2
Input 1: abcde
Input 2: aad
Output: -2, -2, 1
If the input 2 contains reference point, then the code returns zero.
Eg.
An example:
Input 1: abcde
Input 2: cab
Output: 0
The input1 is always odd and input2 is always 10 character max.
The problem I have is that I am not sure how to store these inputs without using strings, array etc. And even if I know how to store them, I cannot compare the inputs like input1[1] = input2[1] because we cannot use arrays/strings.
Is list an useful option with regards to important note?
I have mostly done it with the use of array but not sure how to approach it without the array. I tried to loop a character but it only stores the first character.
My practice code:
#include <iostream>
using namespace std;
int main() {
char input1;
for(int i =0; i < 3; i++ ) //for chacking whether the loops work or not.
{
cin >> input1;
}
cout<< input1;
char input2;
}
Please add any relevant tags.
I hope all the edits help.
KushanMehta proposed a C-ish solution. A more C++ one would be to implement a class wrapping a dynamic array of elements. In C++ it could be:
template <class T>
class MyArr {
protected:
T *arr; // a pointer to the dynamic array
size_t len; // the used length
size_t capacity; // the allocated capacity
...
As it contains a pointer to dynamic array, you cannot rely on default members, and should implement copy and move constructor and assignation operator and a destructor.
In order to be able to use all the goodies of C++ algorithm library, you should declare [c]begin() and [c]end() functions pointing to beginning of array and one past last element.
const T* cbegin() const {
return arr;
}
const T* cend() const {
return arr + len;
}
Then you need a subclass for characters implementing some methods to convert all characters to lower case and remove spaces, sort the array and remove duplicates. You should write io specializations for operator << and >> to be able to input strings from stdin and output them
The MyArr class can be used directly to store the resul value: just derive a specialization for int elements and implement the required specifications.
That may not be really easy, but you will learn C++ that way (not C)
You could do one thing to store the sentences by the use of dynamic memory for each character (sounds absurd but it is the only possible thing without actually worrying about the size of the input)
Meaning you take input till the user wants, in the meanwhile you can use malloc and realloc() for each new character, incrementing the size of your pointer to char for every new character.
(This is probably the way vector etc works on the naive level - not sure of this though)
Code snippet for the same:
#include <iostream>
#include<cstdlib>
#include<cstring>
using namespace std;
int main() {
char temp;
char *sentence = (char*) malloc(2*sizeof(char));
int counter = 0;
while( cin>>temp ){
sentence[counter++] = temp;
sentence = (char*) realloc(sentence, (counter+2)*sizeof(char));
}
sentence[counter] = '\0';
cout<<"The sentence is"<<endl<<strlen(sentence)<<endl<<sentence;
}

Without looping through the string, how can I grab all integers from said string? String class methods?

Rule I must abide by
Do not use loops or character arrays to process strings for any of the questions below. Use member functions of the string class. You can use a loop to read the file and to count the number of processors.
Some Tips
Here are some functions that you might find useful:
File class: getline
String class: find, rfind, substr, length, c_str, constant npos
Misc. functions: atoi, atof
(may require the C standard library for C++, i.e., )
isstringstream
(Both of the above are ways to convert a string to a number.)
Here is an example string I would need to extract:
"46 bits physical, 48 bits virtual"
I can go through the same string twice. I'd want to grab 46 and store it and then do the same for 48.
I'm not sure the best way to go about this. Is it possible to do something like this:
string.find_first_of(integer);
string.find_last_not_of(integer);
Or possibly regex? I think I can use that as long as I don't need to use a 3rd party library or anything like that.
The following ended up working for me.
#include <sstream>
string myString = "hello 47";
int val;
istringstream iss (myString);
iss >> val;
cout << val << endl;
// The output of val will be 47.
Since you indicated in the comments that STL is allowed, you can use a generic programming approach relying on STL algorithms. For example,
#include <iostream>
#include <algorithm>
#include <iterator>
#include <string>
int main()
{
using namespace std;
string haystack = "46 bits physical, 48 bits virtual";
string result;
remove_copy_if(begin(haystack), end(haystack),
back_inserter(result),
[](char c) { return !isspace(c) && !isdigit(c); } );
cout << result;
}
You basically treat the characters in the string as a stream of inputs, from that just filter out all non-digit characters and keeping whatever delimiter char you want to use. My example keeps whitespace as delimiter.
The above gives the output
46 48

Converting integer to string in c++

This is the code I wrote to convert integer to string.
#include <iostream>
using namespace std;
int main()
{
string s;
int b=5;
s.push_back((char)b);
cout<<s<<endl;
}
I expected the output to be 5 but it is giving me blank space.
I know there is another way of doing it using stringstream but I want to know what is wrong in this method?
Character code for numbers are not equal to the integer the character represents in typical system.
It is granteed that character codes for decimal digits are consecutive (N3337 2.3 Character sets, Paragraph 3), so you can add '0' to convert one-digit number to character.
#include <iostream>
using namespace std;
int main()
{
string s;
int b=5;
s.push_back((char)(b + '0'));
cout<<s<<endl;
}
You are interpreting the integer 5 as a character. In ASCII encoding, 5 is the Enquiry control character as you lookup here.
The character 5 on the other hand is represented by the decimal number 53.
As others said, you can't convert an integer to a string the way you are doing it.
IMHO, the best way to do it is using the C++11 method std::to_string.
Your example would translate to:
using namespace std;
int main()
{
string s;
int b=5;
s = to_string(b);
cout<<s<<endl;
}
The problem in your code is that you are converting the integer 5 to ASCII (=> ENQ ASCII code, which is not "printable").
To convert it to ASCII properly, you have to add the ASCII code of '0' (48), so:
char ascii = b + '0';
However, to convert an integer to std::string use:
std::stringstream ss; //from <sstream>
ss << 5;
std::string s = ss.str ();
I always use this helper function in my projects:
template <typename T>
std::string toString (T arg)
{
std::stringstream ss;
ss << arg;
return ss.str ();
}
Also, you can use stringstream,
std::to_string doesn't work for me on GCC
If we were writing C++ from scratch in 2016, maybe we would make this work. However as it choose to be (mostly) backward compatible with a fairly low level language like C, 'char' is in fact just a number, that string/printing algorithms interpret as a character -but most of the language doesn't treat special. Including the cast. So by doing (char) you're only converting a 32 bit signed number (int) to a 8 bit signed number (char).
Then you interpret it as a character when you print it, since printing functions do treat it special. But the value it gets printed to is not '5'. The correspondence is conventional and completely arbitrary; the first numbers were reserved to special codes which are probably obsolete by now. As Hoffman pointed out, the bit value 5 is the code for Enquiry (whatever it means), while to print '5' the character has to contain the value 53. To print a proper space you'd need to enter 32. It has no meaning other than someone decided this was as good as anything, sometime decades ago, and the convention stuck.
If you need to know for other characters and values, what you need is an "ASCII table". Just google it, you'll find plenty.
You'll notice that numbers and letters of the same case are next to each other in the order you expect, so there is some logic to it at least. Beware, however, it's often not intuitive anyway: uppercase letters are before lowercase ones for instance, so 'A' < 'a'.
I guess you're starting to see why it's better to rely on dedicated system functions for strings!

c++ creating ambigram from string

I have a task to implement "void makeAmbigram(char*)" that will print on screen ambigram of latin string or return something like 'ambigram not possible'. Guess it's just about checking if string contains only of SNOXZHI and printing string backwards. Or am I wrong ?
I'm a complete noob when dealing with cpp so that's what I've created :
#include <iostream>
using namespace std;
char[]words;
char[]reversed;
char[] ret_str(char* s)
{
if(*s != '\0')
ret_str(s+1);
return s;
}
void makeAmbigram(char* c)
{
/* finding chars XIHNOZS and printing ambigram */
}
int main()
{
cin>>words;
reversed = ret_str(words);
makeAmbigram(reversed);
return 0;
}
I can reverse string but how to check if my reversed string contains only needed chars ?
I've found some function but it's hard or even imposible to implement it for greater amount of chars : www.java2s.com/Code/C/String/Findcharacterinstringhowtousestrchr.htm
You need to allocate space in your arrays or use std::vector. The arrays word and reversed are just pointers and no space is allocated. The C++ language does not support dynamic arrays; however, the STL provides std::vector which dynamically allocates space as required.
Change:
char[]words;
char[]reversed;
To:
#define MAX_LETTERS 64
char words[MAX_LETTERS + 1]; // + 1 for terminating nul character ('\0')
char reversed[MAX_LETTERS + 1];
Or:
#include <string>
std::string words;
std::string reversed;
Or:
#include <vector>
std::vector<char> words;
std::vector<char> reversed;
As far as the ambigram rules go, you need to talk to your instructor. Also, if this is homework, add a tag indicating so.
Hint: The std::string data type has some reverse iterators which may be of use to you.
std::string has an entire family of member functions along the lines of find_first_of. You can pass in a string containing all the letters your ambigram test requires, and they'll find whether any of those letters are present in the source string.
The complete list of string functions is available here.
As for the definition of ambigrams, given the wiki page you've included in the question...you need to check if a letter is legible if viewed upside down, for eg. u/n, w/m, d/p, q/b and so on. There are of course more complex rules was well, for eg. 'ui' can resemble 'm' if viewed upside down.
However, if you're only required to check if your string contains only SNOXZHI, you can look into a regular expression (regex) for the same, and compare input string character-wise to your regex.