FYI: I am new to programming.
I have an arraysize of 10 and the sentinel value is 0.
My original array is [1 2 3] ( user input) but my reverse is [0 0 0 0 0 0 0 3 2 1].
I need help to make my reverse array [3 2 1].
Here is my code:
int temp;
for (int i = 0; i < arraysize/2; i++)
{
temp = array[arraysize-1-i];
array[arraysize - i - 1] = array[i];
array[i] = temp;
}
cout << "The reverse array: ";
for (int i = 0; i < arraysize; i++)
cout << array[i]<< ' ';
cout << endl;
Just use the standard library algorithms
auto end = std::find(std::begin(array),std::end(array),0);
std::reverse(std::begin(array),end);
//And if you only want to print the non-zero values:
size_t effectiveArraySize = end - std::begin(array);
If the fixed size array is not part of your requirement, you should put your user data in a vector that automaticaly grows as large as you need, instead of using an array that might turn out to be too small:
std::vector<int> v;
while(true) {
int t;
cin >> t;
if (t == 0) {
break;
}
v.push_back(t);
}
std::reverse(v.begin(),v.end());
That way, you don't have any sentinel values in your array / vector to begin with.
Note: Using the respective functions from the STL (std::reverse and std::find) is better, I was just guessing that you are bound to implement this on your own.
Step one: Write a proper reverse function. One that takes (a pointer to) the beginning as well as (a pointer to) the end of the range that should be reversed.
Step two: Write a function to find (the first position of) your sentinel in an array (given via beginning and end, again)
Step three: Connect the two: Reverse from the beginning to the position of your sentinel.
Example without templates:
void reverse(int * from, int * to) {
while ((to - from) > 1) {
--to;
int temp = *from;
*from = *to;
*to = temp;
++from;
}
}
int const * find(int const * from,
int const * const to,
int const value) {
while ((from != to) && (*from != value)) {
++from;
}
return from;
}
void reverse_until (int * const from,
int * const to,
int const sentinel) {
int const * const position_sentinel = find(from, to, sentinel);
reverse(from, from + (position_sentinel - from));
// return the sentinel position from this function
// if you want only the reversed part
}
Tested with:
int main() {
int test[10];
for (size_t i = 0; i < 10; ++i) {
test [i] = i + 1;
}
reverse_until (test, test + 10, 6);
copy(test, test + 10, ostream_iterator<int>{cout, " "});
return 0;
}
(live here)
You need to find the actual length of the array, before performing the reverse operation, and then use that length for all further operations.
Like this:
int actualArraySize = 0;
while(actualArraySize < arraysize && array[actualArraySize]!=0)
{
actualArraySize++;
}
int temp;
for (int i = 0; i < actualArraySize/2; i++)
{
temp = array[actualArraySize-1-i];
array[actualArraySize - i - 1] = array[i];
array[i] = temp;
}
cout << "The reverse array: ";
for (int i = 0; i < actualArraySize; i++)
cout << array[i]<< ' ';
cout << endl;
Note that, actualArraySize can be less than or equal to arraysize, but, not more than it, because of the condition in while(actualArraySize < arraysize && array[actualArraySize]!=0), which means that stop when either a 0 is found or the size of the array is reached.
Related
First of all, sorry for the mis-worded title. I couldn't imagine a better way to put it.
The problem I'm facing is as follows: In a part of my program, the program counts occurences of different a-zA-Z letters and then tells how many of each letters can be found in an array. The problem, however, is this:
If I have an array that consists of A;A;F;A;D or anything similar, the output will be this:
A - 3
A - 3
F - 1
A - 3
D - 1
But I am required to make it like this:
A - 3
F - 1
D - 1
I could solve the problem easily, however I can't use an additional array to check what values have been already echoed. I know why it happens, but I don't know a way to solve it without using an additional array.
This is the code snippet (the array simply consists of characters, not worthy of adding it to the snippet):
n is the size of array the user is asked to choose at the start of the program (not included in the snippet).
initburts is the current array member ID that is being compared against all other values.
burts is the counter that is being reset after the loop is done checking a letter and moves onto the next one.
do {
for (i = 0; i < n; i++) {
if (array[initburts] == array[i]) {
burts++;
}
}
cout << "\n\n" << array[initburts] << " - " << burts;
initburts++;
burts = 0;
if (initburts == n) {
isDone = true;
}
}
while (isDone == false);
Do your counting first, then loop over your counts printing the results.
std::map<decltype(array[0]), std::size_t> counts;
std::for_each(std::begin(array), std::end(array), [&counts](auto& item){ ++counts[item]; });
std::for_each(std::begin(counts), std::end(counts), [](auto& pair) { std::cout << "\n\n" << pair.first << " - " pair.second; });
for (i = 0; i < n; i++)
{
// first check if we printed this character already;
// this is the case if the same character occurred
// before the current one:
bool isNew = true;
for (j = 0; j < i; j++)
{
// you find out yourself, do you?
// do not forget to break the loop
// in case of having detected an equal value!
}
if(isNew)
{
// well, now we can count...
unsigned int count = 1;
for(int j = i + 1; j < n; ++j)
count += array[j] == array[i];
// appropriate output...
}
}
That would do the trick and retains the array as is, however is an O(n²) algorithm. More efficient (O(n*log(n))) is sorting the array in advance, then you can just iterate over the array once. Of course, original array sequence gets lost then:
std::sort(array, array + arrayLength);
auto start = array;
for(auto current = array + 1; current != array + arrayLength; ++current)
{
if(*current != *start)
{
auto char = *start;
auto count = current - start;
// output char and count appropriately
}
}
// now we yet lack the final character:
auto char = *start;
auto count = array + arrayLength - start;
// output char and count appropriately
Pointer arithmetic... Quite likely that your teacher gets suspicious if you just copy this code, but it should give you the necessary hints to make up your own variant (use indices instead of pointers...).
I would do it this way.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
string s;
vector<int> capCount(26, 0), smallCount(26, 0);
cout << "Enter the string\n";
cin >> s;
for(int i = 0; i < s.length(); ++i)
{
char c = s.at(i);
if(c >= 'A' && c <= 'Z')
++capCount[(int)c - 65];
if(c >= 'a' && c <= 'z')
++smallCount[(int)c - 97];
}
for(int i = 0; i < 26; ++i)
{
if(capCount[i] > 0)
cout << (char) (i + 65) << ": " << capCount[i] << endl;
if(smallCount[i] > 0)
cout << (char) (i + 97) << ": " << smallCount[i] << endl;
}
}
Note: I have differentiated lower and upper case characters.
Here's is the sample output:
output
*Sorry about my poor English. If there is anything that you don't understand, please tell me so that I can give you more information that 'make sence'.
**This is first time asking question in Stackoverflow. I've searched some rules for asking questions correctly here, but there should be something I missed. I welcome all feedback.
I'm currently solving algorithm problems to improve my skill, and I'm struggling with one question for three days. This question is from https://algospot.com/judge/problem/read/RESTORE , but since this page is in KOREAN, I tried to translate it in English.
Question
If there are 'k' pieces of partial strings given, calculate shortest string that includes all partial strings.
All strings consist only lowercase alphabets.
If there are more than 1 result strings that satisfy all conditions with same length, choose any string.
Input
In the first line of input, number of test case 'C'(C<=50) is given.
For each test case, number of partial string 'k'(1<=k<=15) is given in the first line, and in next k lines partial strings are given.
Length of partial string is between 1 to 40.
Output
For each testcase, print shortest string that includes all partial strings.
Sample Input
3
3
geo
oji
jing
2
world
hello
3
abrac
cadabra
dabr
Sample Output
geojing
helloworld
cadabrac
And here is my code. My code seems to work perfect with Sample Inputs, and when I made test inputs for my own and tested, everything worked fine. But when I submit this code, they say my code is 'wrong'.
Please tell me what is wrong with my code. You don't need to tell me whole fixed code, I just need sample inputs that causes error with my code. Added code description to make my code easier to understand.
Code Description
Saved all input partial strings in vector 'stringParts'.
Saved current shortest string result in global variable 'answer'.
Used 'cache' array for memoization - to skip repeated function call.
Algorithm I designed to solve this problem is divided into two function -
restore() & eraseOverlapped().
restore() function calculates shortest string that includes all partial strings in 'stringParts'.
Result of resotre() is saved in 'answer'.
For restore(), there are three parameters - 'curString', 'selected' and 'last'.
'curString' stands for currently selected and overlapped string result.
'selected' stands for currently selected elements of 'stringParts'. Used bitmask to make my algorithm concise.
'last' stands for last selected element of 'stringParts' for making 'curString'.
eraseOverlapped() function does preprocessing - it deletes elements of 'stringParts' that can be completly included to other elements before executing restore().
#include <algorithm>
#include <iostream>
#include <vector>
#include <cstring>
#include <string>
#define MAX 15
using namespace std;
int k;
string answer; // save shortest result string
vector<string> stringParts;
bool cache[MAX + 1][(1 << MAX) + 1]; //[last selected string][set of selected strings in Bitmask]
void restore(string curString, int selected=0, int last=0) {
//base case 1
if (selected == (1 << k) - 1) {
if (answer.empty() || curString.length() < answer.length())
answer = curString;
return;
}
//base case 2 - memoization
bool& ret = cache[last][selected];
if (ret != false) return;
for (int next = 0; next < k; next++) {
string checkStr = stringParts[next];
if (selected & (1 << next)) continue;
if (curString.empty())
restore(checkStr, selected + (1 << next), next + 1);
else {
int check = false;
//count max overlapping area of two strings and overlap two strings.
for (int i = (checkStr.length() > curString.length() ? curString.length() : checkStr.length())
; i > 0; i--) {
if (curString.substr(curString.size()-i, i) == checkStr.substr(0, i)) {
restore(curString + checkStr.substr(i, checkStr.length()-i), selected + (1 << next), next + 1);
check = true;
break;
}
}
if (!check) { // if there aren't any overlapping area
restore(curString + checkStr, selected + (1 << next), next + 1);
}
}
}
ret = true;
}
//check if there are strings that can be completely included by other strings, and delete that string.
void eraseOverlapped() {
//arranging string vector in ascending order of string length
int vectorLen = stringParts.size();
for (int i = 0; i < vectorLen - 1; i++) {
for (int j = i + 1; j < vectorLen; j++) {
if (stringParts[i].length() < stringParts[j].length()) {
string temp = stringParts[i];
stringParts[i] = stringParts[j];
stringParts[j] = temp;
}
}
}
//deleting included strings
vector<string>::iterator iter;
for (int i = 0; i < vectorLen-1; i++) {
for (int j = i + 1; j < vectorLen; j++) {
if (stringParts[i].find(stringParts[j]) != string::npos) {
iter = stringParts.begin() + j;
stringParts.erase(iter);
j--;
vectorLen--;
}
}
}
}
int main(void) {
int C;
cin >> C; // testcase
for (int testCase = 0; testCase < C; testCase++) {
cin >> k; // number of partial strings
memset(cache, false, sizeof(cache)); // initializing cache to false
string inputStr;
for (int i = 0; i < k; i++) {
cin >> inputStr;
stringParts.push_back(inputStr);
}
eraseOverlapped();
k = stringParts.size();
restore("");
cout << answer << endl;
answer.clear();
stringParts.clear();
}
}
After determining which string-parts can be removed from the list since they are contained in other string-parts, one way to model this problem might be as the "taxicab ripoff problem" problem (or Max TSP), where each potential length reduction by overlap is given a positive weight. Considering that the input size in the question is very small, it seems likely that they expect a near brute-force solution, with possibly some heuristic and backtracking or other form of memoization.
Thanks Everyone who tried to help me solve this problem. I actually solved this problem with few changes on my previous algorithm. These are main changes.
In my previous algorithm I saved result of restore() in global variable 'answer' since restore() didn't return anything, but in new algorithm since restore() returns mid-process answer string I no longer need to use 'answer'.
Used string type cache instead of bool type cache. I found out using bool cache for memoization in this algorithm was useless.
Deleted 'curString' parameter from restore(). Since what we only need during recursive call is one previously selected partial string, 'last' can replace role of 'curString'.
CODE
#include <algorithm>
#include <iostream>
#include <vector>
#include <cstring>
#include <string>
#define MAX 15
using namespace std;
int k;
vector<string> stringParts;
string cache[MAX + 1][(1 << MAX) + 1];
string restore(int selected = 0, int last = -1) {
if (selected == (1 << k) - 1) {
return stringParts[last];
}
if (last == -1) {
string ret = "";
for (int next = 0; next < k; next++) {
string resultStr = restore(selected + (1 << next), next);
if (ret.empty() || ret.length() > resultStr.length())
ret = resultStr;
}
return ret;
}
string& ret = cache[last][selected];
if (!ret.empty()) {
cout << "cache used in [" << last << "][" << selected << "]" << endl;
return ret;
}
string curString = stringParts[last];
for (int next = 0; next < k; next++) {
if (selected & (1 << next)) continue;
string checkStr = restore(selected + (1 << next), next);
int check = false;
string resultStr;
for (int i = (checkStr.length() > curString.length() ? curString.length() : checkStr.length())
; i > 0; i--) {
if (curString.substr(curString.size() - i, i) == checkStr.substr(0, i)) {
resultStr = curString + checkStr.substr(i, checkStr.length() - i);
check = true;
break;
}
}
if (!check)
resultStr = curString + checkStr;
if (ret.empty() || ret.length() > resultStr.length())
ret = resultStr;
}
return ret;
}
void EraseOverlapped() {
int vectorLen = stringParts.size();
for (int i = 0; i < vectorLen - 1; i++) {
for (int j = i + 1; j < vectorLen; j++) {
if (stringParts[i].length() < stringParts[j].length()) {
string temp = stringParts[i];
stringParts[i] = stringParts[j];
stringParts[j] = temp;
}
}
}
vector<string>::iterator iter;
for (int i = 0; i < vectorLen - 1; i++) {
for (int j = i + 1; j < vectorLen; j++) {
if (stringParts[i].find(stringParts[j]) != string::npos) {
iter = stringParts.begin() + j;
stringParts.erase(iter);
j--;
vectorLen--;
}
}
}
}
int main(void) {
int C;
cin >> C;
for (int testCase = 0; testCase < C; testCase++) {
cin >> k;
for (int i = 0; i < MAX + 1; i++) {
for (int j = 0; j < (1 << MAX) + 1; j++)
cache[i][j] = "";
}
string inputStr;
for (int i = 0; i < k; i++) {
cin >> inputStr;
stringParts.push_back(inputStr);
}
EraseOverlapped();
k = stringParts.size();
string resultStr = restore();
cout << resultStr << endl;
stringParts.clear();
}
}
This algorithm is much slower than the 'ideal' algorithm that the book I'm studying suggests, but it was fast enough to pass this question's time limit.
I'm practicing in programming and I generating all combinations in c++. I know how to generate all combination in
certain length
My result is something like that
A A A
A A B
A A C
A B A
A B B
A B C
A C A
A C B
A C C
B A A
.....
and my problem is, I don't know, how to generate all combinations with unknown length. For example I want word length = 5 and program will generate all combination in exactly length 5. How to do it?
A A A A A
A A A A B
A A A A C
A A A B A
.........
(Sorry for my english)
See the link Print all permutations with repetition of characters
The below recursive function in the page, can create last+1 length permutations.
/* The main function that recursively prints all repeated
permutations of the given string. It uses data[] to store all
permutations one by one */
void allLexicographicRecur (char *str, char* data, int last, int index)
{
int i, len = strlen(str);
// One by one fix all characters at the given index and recur for
// the/ subsequent indexes
for ( i=0; i<len; i++ )
{
// Fix the ith character at index and if this is not the last
// index then recursively call for higher indexes
data[index] = str[i] ;
// If this is the last index then print the string stored in
// data[]
if (index == last)
printf("%s\n", data);
else // Recur for higher indexes
allLexicographicRecur (str, data, last, index+1);
}
}
I think this can serve your purpose.
Call allLexicographicRecur with the required (length-1) value for the 'last' parameter.
This is actually nothing more than counting.
If you have the letters A, B, and C, you are counting in base 3.
A is 0, B is 1 and C is 2.
Quick and dirty:
#include <string>
#include <iostream>
int main()
{
for(int i = 0; i < 100; i++) {
const int base = 3;
const char zero_char = 'A';
const size_t length = 5;
std::string out;
for(int n = i; n > 0; ) {
int d = n%base;
out = static_cast<char>(zero_char + d) + out;
n /= base;
}
while(out.length() < length) out = zero_char + out;
std::cout << out << '\n';
}
}
see it live
The possible combinations are baselength, so if you want all combinations for A, B, C with 5 digits, change the limit of the first for loop to 35 ( = 243):
for(int i = 0; i < 243; i++)
You may use something like:
bool increase(const std::string& s, std::vector<std::size_t>& it)
{
for (std::size_t i = 0, size = it.size(); i != size; ++i) {
const std::size_t index = size - 1 - i;
++it[index];
if (it[index] >= s.size()) {
it[index] = 0;
} else {
return true;
}
}
return false;
}
void do_job(const std::string& s,
const std::vector<std::size_t>& it)
{
for (std::size_t i = 0; i != it.size(); ++i) {
std::cout << s[it[i]] << " ";
}
std::cout << std::endl;
}
void cartesian_product(const std::string& s, std::size_t n)
{
std::vector<std::size_t> it(n, 0u);
do {
do_job(s, it);
} while (increase(s, it));
}
Demo
I have a null terminated array of chars. Also known as a c-string. I have written a function that will shift the elements at each index left, <---- by a given number of indexes. For example, when the char array of "hello world" is passed to the function, with a shiftBy value of 3, it should transform the char array to be: "lo worldhel".
Currently, this function works for all strings that <= 11 elelements. Anything over that and the last three spots in the array don't get shifted. Keep in mind, the very last index is holding the null terminator!
This is a tricky one and I have been stuck for hours. I also can't use any standard functions or vectors, I am stuck with these deprecated arrays and simple loops. So please don't troll with "Why don;t you use blank function"....because trust me, if I could I wouldn't be here.
Here is the code, have at at:
void shiftLeft (char szString[], int size, int shiftBy)
{
if(shiftBy > size){
shiftBy = shiftBy - size;
}
if(size == 1){
//do nothing, do nothing, exit function with no change made to myarray
}
else{
char temp;
//for loop to print the array with indexes moved up (to the left) <-- by 2
for (int i = 0; i <= size-shiftBy; i++)//size = 11
{//EXAMPLE shift by 3 for a c-string of `hello world`
if(i < size-shiftBy){
temp = szString[shiftBy + i];//temp = h
szString[shiftBy + i] = szString[i];//d becomes l
szString[i] = temp;//h becomes l
}
else{//it will run once while i=8
temp = szString[i];//temp = l
szString[i] = szString[i+1];//8th element becomes h
szString[i+1] = szString[size-1];//9th element becomes e
szString[size-1] = temp;//last element becomes l
}
}
}
}
If the only purpose you're trying to accomplish is shifting chars in a terminated string left with rotation (and judging by your sample of "helloworld" resulting in "loworldhel" after a 3-shift, that seems to be the case), you're making this much harder than it needs to be.
The traditional algorithm to do this in O(N) time with no temporary space requirements is to reverse the left-side of the shift, then the entire sequence, then the right side of the shift, all based from the beginning of the sequence. For example, suppose we want to left-shift the following string 3 slots:
1234567890
First, reverse the first shiftBy slots
1234567890
^-^
3214567890
Second, reverse the entire sequence
3214567890
^--------^
0987654123
Finally, reverse the (length-shiftBy) slots:
0987654123
^-----^
4567890123
Using the standard library would make this trivial, but apparently you're prof considers that... cheating. Without using any library apis the above algorithm isn't very hard regardless:
#include <iostream>
void shiftLeft(char sz[], size_t shiftBy)
{
const char *p = sz;
while (*p) ++p;
std::size_t len = p - sz;
if (len > 1 && (shiftBy %= len))
{
char *ends[] = { sz+shiftBy, sz+len, sz+(len - shiftBy) };
for (std::size_t i=0; i<3; ++i)
{
char *start = sz, *end = ends[i];
while (start < --end)
{
char ch = *start;
*start++ = *end;
*end = ch;
}
}
}
}
int main()
{
char sz[] = "1234567890";
std::cout << sz << '\n';
shiftLeft(sz, 11);
std::cout << sz << '\n';
shiftLeft(sz, 4);
std::cout << sz << '\n';
shiftLeft(sz, 1);
std::cout << sz << '\n';
shiftLeft(sz, 20);
std::cout << sz << '\n';
}
Output
1234567890
2345678901
6789012345
7890123456
7890123456
If you're really set on doing this in temp space, so be it, but I cannot possibly fathom why you would do so.
Best of luck.
From azillionmonkeys.com/qed/case8.html
void shiftLeft(char szString[], int size, int shiftBy) {
int c, tmp, v;
if (size <= 0) return;
if (shiftBy < 0 || shiftBy >= size) {
shiftBy %= size;
if (shiftBy < 0) shiftBy += size;
}
if (shiftBy == 0) return;
c = 0;
for (v = 0; c < size; v++) {
int t = v, tp = v + shiftBy;
char tmp = szString[v];
c++;
while (tp != v) {
szString[t] = szString[tp];
t = tp;
tp += shiftBy;
if (tp >= size) tp -= size;
c++;
}
szString[t] = tmp;
}
}
I'm getting the longest consecutive increasing numbers in an array with 10 items
int list[] = {2,3,8,9,10,11,12,2,6,8};
int start_pos = 0;
int lenght=0; // lenght of the sub-~consetuve
for (int a =0; a <=9; a++ )
{
if ((list[a]+1) == (list[a+1])) {
// continue just the string;
lenght++;
} else {
start_pos = a;
}
}
cout << lenght << " and start in " << start_pos;
getchar();
but it not working, it should return in length & start_pos ( 3 and lenght 4 ) because longest increasing is from 9 , 10 , 11 , 12 but it not working.
Assuming you actually meant subsequence, just guess the digit your sequence starts with and then run a linear scan. If you meant substring, it's even easier --- left as an exercise to OP.
The linear scan goes like this:
char next = <guessed digit>;
int len = 0;
char *ptr = <pointer to input string>;
while (*ptr) {
if ((*ptr) == next) {
next = next + 1;
if (next > '9') next = '0';
len++;
}
ptr++;
}
Now wrap that with a loop that sets to all digits from '0' to '9' and you are done, pick the one that gives the longest length.
simple idea: start point, end point and length of the sequence.
Run loop i
sequence will start whenever current number (at index i) less than next number 1 => start point set = i
it ends when condition above false => get end point => get the length = end -start (make more variable called max to compare lengths) => result could be max, reset start point, end point = 0 again when end of sequence
I made it myself:
#include <iostream>
using namespace std;
bool cons(int list[] , int iv) { bool ret=true; for (int a=0; a<=iv; a++) { if (list[a] != list[a+1]-1) ret=false; } return ret; }
void main() {
int str[10] = {12,13,15,16,17,18,20,21};
int longest=0;
int pos=0;
for (int lenght=1; lenght <= 9; lenght++) {
int li[10];
for (int seek=0; seek <= 9; seek++) {
for (int kor=0; kor <= lenght-1; kor ++ ) {
li[kor] = str[seek+kor];
}
if (cons(li , lenght-2)) {
longest = lenght;
pos=seek;
}
}
}
for (int b=pos; b <= pos+longest-1; b++) cout << str[b] << " - "; cout << "it is the end!" << endl; getchar();
}