Reverse an array without affecting special characters - c++

Is it possible to reverse an array without affecting the special characters ? By special characters, I mean anything characters not included from 'a' to 'z' and 'A' to 'Z'. I am short of ideas to build the algorithm, I still haven't it figured out.

One simple solution would be to Simple Solution:
1) Create a temporary character array --> ex: myArr[].
2) Copy alphabetic characters from the given array to myArr[].
3) Reverse myArr[] using standard string reversal algorithm.
4) Now traverse input string and myArr in a single loop. Wherever there is alphabetic character is input string, replace it with current character of myArr[].
Little problem with above solution, it requires extra space and it does two traversals of input string.
You can reverse with one traversal and without extra space. Below is algorithm.
1) Let input string be 'str[]' and length of string be 'a'
2) l = 0, r = a-1
3) While l is smaller than r, do following
a) If str[l] is not an alphabetic character, do l++
b) Else If str[r] is not an alphabetic character, do r--
c) Else swap str[l] and str[r]

Here's a solution that will do it "in place" in one pass.
bool isspecial(char c)
{
if ((c >= 'a') && (c <= 'z')) return false;
if ((c >= 'A') && (c <= 'Z')) return false;
return true;
}
void rev(char* array, int N)
{
int i = 0; // i points to the first index of the array
int j = N - 1; // j points to the last index of the array
while (i < j)
{
if (isspecial(array[i]))
{
i++;
}
else if (isspecial(array[j]))
{
j--;
}
else
{
char tmp = array[i];
array[i] = array[j];
array[j] = tmp;
i++;
j--;
}
}
}

Console.WriteLine("enter any string");
string str = Console.ReadLine();
string[] revstr = new string[str.Length];
for (int i = 0; i < str.Length; i++)
{
int ch = Convert.ToInt16(str.ToLower()[i]);
if ((ch < 97 || ch > 122))
{
revstr[i] = str[i].ToString();
}
}
for (int k = str.Length - 1; k >= 0; k--)
{
int ch = Convert.ToInt16(str.ToLower()[k]);
if (!(ch < 97 || ch > 122))
{
for (int j = 0; j < str.Length; j++)
{
if (revstr[j] == null)
{
revstr[j] = str[k].ToString();
break;
}
}
}
}
for (int s = 0; s < revstr.Length; s++)
{
Console.Write(revstr[s]);
}

If you want the position of the special characters to remain the same and the rest of the string to be reversed then this should work -
#include <iostream>
using namespace std;
void swap(char& a, char& b)
{
char temp = a;
a = b;
b = temp;
}
int main()
{
string s = "Hell$o World";
for(int i = 0, j = s.length() -1;i < s.length()/2; i++, j--) {
while((s[i] <= 'a' && s[i] >= 'Z') || s[i] >= 'z' || s[i] <= 'A') {
i++;
}
while((s[j] <= 'a' && s[j] >= 'Z') || s[j] >= 'z' || s[j] <= 'A') {
j--;
}
swap(s[i], s[j]);
}
cout << s << endl; //dlro$W olleH
return 0;
}

Related

Read a char array and modify it

So for this program the user gives a text and it must print the text back modifying in these ways by adding and removing space between words:
Each line should contain 60 characters and be aligned left and right
In each line the biggest space between two words must be bigger than the smallest by only one character and a bigger space must be righter than a smaller one. This is what I have managed to do yet, but without any success.
I tried C++ strings instead of a char array but my knowledge about them is limited yet.
#include <iostream>
using namespace std;
bool isletter(char c) {
return c >= 'a' and c <= 'z' or c >= 'A' and c <= 'Z';
}
int main() {
int c, i = 0, constant = 0, counter = 0;
char text[1500], original[1500];
do {
c = getchar();
original[i] = c;
i++;
} while (c != EOF);
for (int j = 0; j <= i; j++) {
if (original[j] == ' ') {
int n = 0;
j = constant;
while (not isletter(original[j])) {
n++;
text[constant] = original[j];
j = j + n;
}
counter++;
} else if (text[j] == '\n') {
text[j] = ' ';
counter++;
} else {
text[j] = original[j];
counter++;
}
}
for (int i = 0; i < counter; i++) {
cout << text[i];
}
}

How to ignore white space and marks when encrypting a string variable in c++

I am trying to encrypt a string with white space and a question mark on it, for example, I am going to encrypt all the alphabet into numbers based on the order of the alphabet, but when I turn the string into numbers white space and question mark also gets enumerated how do I ignore that?
example)
int main() {
string alphabet;
int encrypted_code;
int first_int = 1, second_int = 2, third_int = 3;
string text = "hey what is your name?";
for (char ch = 'a'; ch <= 'z'; ch++) {
alphabet += ch;
}
for (int i = 0; i < text.length(); i++) {
encrypted_code = alphabet.find(text[i]);
if (i == 0 || i % 3 == 0) {
encrypted_code = encrypted_code + first_int;
}
cout << encrypted_code << " ";
}
}
Use an if statement to only work on letters:
for (int i = 0; i < text.length(); i++) {
if ('a' <= text[i] && text[i] <= 'z') {
// rest of your code goes here
}
}

If the only input is a String and an additional String is created, is the function O(n) space complexity?

For example:
string longestPalStartingAtIndex(string s, int index) {
int i = index - 1;
int j = index + 1;
while (j < s.size() && s.at(index) == s.at(j)) j++;
while (i >= 0 && j < s.size()) {
if (s.at(i) == s.at(j)) {
i--; j++;
}
else {break;}
}
return s.substr(i + 1, (j - 1) - (i + 1) + 1);
}
string longestPalindrome(string s) {
string longest; string temp;
for (int i = 0; i < s.size(); i++) {
temp = longestPalStartingAtIndex(s, i);
if (longest.size() < temp.size()) longest = temp;
}
return longest;
}
In longestPalindrome, since n is the string s or the length of it, is creating an additional string (meant to store some substring of s) going to make the function O(n) space complexity?
Yes. You're correct. The code you've shown has O(s.size()) space complexity.
Arguably the function calls to longestPalStartingAtIndex will also copy s and require space, but in the end we're talking about O(some_constant * s.size()) so it is still O(s.size()).

About the solution for "reverse-string" in leetcode

https://leetcode.com/problems/reverse-string/
Here is my solution:
class Solution {
public:
string reverseString(string s) {
// if(s.size() == 0 || s.size() == 1)
// return s;
string::size_type i = 0;
string::size_type j = s.size() - 1;
while (i < j)
{
char temp = s[i];
s[i] = s[j];
s[j] = temp;
i++;
j--;
}
return s;
}
};
But this solution is not passed.
When i uncomment these two lines: if(s.size() == 0 || s.size() == 1) return s;, the code pass. i am confused, i think these code are equal.
When the length is 0 you get out of bounds access (j becomes a large number as it is unsigned).
The length 1 case should be safe to keep commented.

Convert String to Uppercase Decussate in C++

I have this code:
Str UpperCase()
{
Str Result;
int i = 0;
for (; string[i]; i++)
{
if (string[i] <= 'z' && string[i] >= 'a')
{
string[i] -= 32;
}
Result.string[i] = string[i];
}
Result.string[i] = 0;
return Result;
}
It will make String Uppercase.
What should I do if I want it to be Decussate?
Example: hi my name is pooya ==> Hi My NaMe Is PoOyA
Sorry for my bad english
and Thanks ;)
Str UpperCase()
{
Str Result;
int i = 0;
int decussate = 0;
for (; string[i]; i++)
{
if (string[i] <= 'z' && string[i] >= 'a')
{
decussate++;
if( decussate%2 == 1 ){
string[i] -= 32;
}
}
Result.string[i] = string[i];
}
Result.string[i] = 0;
return Result;
}
Add int decussate, by changing it between an odd and an even number everytime a lowercase letter is found, it will create a pattern in which the 1,3,5,7,and so on letters will be capitalized, assuming the string is in lowercase.