Reverse a String Without Affecting Special Characters

Reverse a String without affecting special characters

The problematic part is the call temp.charAt(i) in

for(int i=0;i<ori.length();i++){
char c=ori.charAt(i);
if(((c>=65)&&(c<=90))||((c>=97)&&(c<122)))
ori.replace(c, temp.charAt(i));
}

The string temp may not have the length of ori. The reason for this is the if-condition in the first loop

for(int i=0;i<ori.length();i++) {
char c=ori.charAt(i);
if(((c>=65)&&(c<=90))||((c>=97)&&(c<122)))
temp=c+temp;
}

So accessing the position i in temp (as part of the second loop) may result in the java.lang.StringIndexOutOfBoundsException.

reverse string without affect special characters in php

One solution without regex would be:

function revert(string $input) : string {
// get all characters; asuming ascii
$chars = [];
for($i = 0; $i < strlen($input); $i++) {
if (ctype_alpha($input[$i])) {
$chars[] = $input[$i];
}
}

// replace characters
for($i = 0;$i < strlen($input); $i++) {
if (ctype_alpha($input[$i])) {
$input[$i] = array_pop($chars);
}
}

return $input;
}

$val = "<brinh!>";
echo revert($val);

Having two pointers, one running from left to right and one from right to left would also be possible. But much less readable.

Reverse string without reversing special characters using Javascript

You can't modify string in this way, strings are immutable in JavaScript

var str = "abcdef";console.log(str[1])str[1] = "x"
console.log(str)

Reversing string without affecting any special characters

From your regular expression, it seems your criterion for "special characters" is anything other than the letters A to Z.

You can use String.prototype.replace with a regular expression to match sequences of letters, then provide a replace function that modifies the match before replacing it, e.g.

var stringIn = 'My! name.is@rin';var rev = stringIn.replace(/[a-z]+/gi, function(s){return s.split('').reverse().join('')});document.write(rev); // yM! eman.si@nir

Reverse string without affecting specific characters that user can input

In your code, when you swap values at 2 positions, they both have to be valid characters, meaning, both alphabetic and not of the characters of ignore. Second issue is you are equating a character of ignore directly with left pointer of the rev string in ign[i] == str[l]. They need not coincide index-wise this way.


Algorithm:

  • Create a set of all the characters in ignore.
  • Create a result array of type char with length same as rev.
  • Create another reserved boolean array with length same as rev.
  • Now, loop on rev char by char. If it is non-alphabetic or one of the chars of ignore, fix that position with that char. In reserved, mark this index as true as we can't mess with this index now.
  • Once done, move again on the string rev from left to right and this time only consider alphabetic chars and the ones which aren't a part of ignore. Now, add them in a reverse way inside result to actually store in the reversed state. Note that the next non-reserved location won't always be sequential in nature with a simple ptr--. We would need a while loop inside to get the next non reserved seat and insert them there.

Snippet:

public static String reverseString(String rev, String ignore) {
Set<Character> set = new HashSet<>();
for(int i = 0; i < ignore.length(); ++i){
set.add(ignore.charAt(i));
}

char[] result = new char[rev.length()];
boolean[] reserved = new boolean[rev.length()];


for(int i = 0; i < rev.length(); ++i){
if(!Character.isAlphabetic(rev.charAt(i)) || set.contains(rev.charAt(i))){
result[i] = rev.charAt(i);
reserved[i] = true;
}
}

int ptr = rev.length() - 1;
for(int i = 0; i < rev.length(); ++i){
if(Character.isAlphabetic(rev.charAt(i)) && !set.contains(rev.charAt(i))){
while(ptr >= 0 && reserved[ptr]) ptr--;
result[ptr--] = rev.charAt(i);
}
}

return new String(result);
}

Online Demo

How to reverse an array of strings without changing the position of special characters in C#

A basic solution with regex and LINQ. Try it online.

public static void Main()
{
Console.WriteLine("Marshall! Hello.");
Console.WriteLine(Reverse("Marshall! Hello."));
}

public static string Reverse(string source)
{
// we split by groups to keep delimiters
var parts = Regex.Split(source, @"([^a-zA-Z0-9])");
// if we got a group of valid characters
var results = parts.Select(x => x.All(char.IsLetterOrDigit)
// we reverse it
? new string(x.Reverse().ToArray())
// or we keep the delimiters as it
: x);
// then we concat all of them
return string.Concat(results);
}

The same solution without LINQ. Try it online.

public static void Main()
{
Console.WriteLine("Marshall! Hello.");
Console.WriteLine(Reverse("Marshall! Hello."));

}

public static bool IsLettersOrDigits(string s)
{
foreach (var c in s)
{
if (!char.IsLetterOrDigit(c))
{
return false;
}
}
return true;
}

public static string Reverse(char[] s)
{
Array.Reverse(s);
return new string(s);
}


public static string Reverse(string source)
{
var parts = Regex.Split(source, @"([^a-zA-Z0-9])");

var results = new List<string>();
foreach(var x in parts)
{
results.Add(IsLettersOrDigits(x)
? Reverse(x.ToCharArray())
: x);
}
return string.Concat(results);
}


Related Topics



Leave a reply



Submit