I have a string variable. I want to swap the two characters in the string word.
I want to randomly swap two characters which are close to each other.
This is what I have done:
I have done like this but in some words I get error.
string word = txtWord.Text;
Random rand = new Random();
int randomNumber= rand.Next(0, word.Length);
string swappedWord = SwapCharacters(lastWord, randomNumber, randomNumber + 1);
private string SwapCharacters(string value, int position1, int position2)
{
char[] array = value.ToCharArray(); // Convert a string to a char array
char temp = array[position1]; // Get temporary copy of character
array[position1] = array[position2]; // Assign element
array[position2] = temp; // Assign element
return new string(array); // Return string
}
Use a StringBuilder:
//If you want to replace
StringBuilder sb = new StringBuilder(theString);
sb[index] = newChar;
theString = sb.ToString();
//Swap
string input = "AXBYCZ"; //Sample String
StringBuilder output = new StringBuilder();
char[] characters = input.ToCharArray();
for (int i = 0; i < characters.Length; i++)
{
if (i % 2 == 0)
{
if((i+1) < characters.Length )
{
output.Append(characters[i + 1]);
}
output.Append(characters[i]);
}
}
Just change the line as below:
int randomNumber= rand.Next(0, word.Length -1 );
Let's see if it works.
Try this. Also add checks if the word is empty.
int randomNumber= rand.Next(0, word.Length - 1);
Try this code. It is easiest to change your code
int randomNumber= rand.Next(0, word.Length-2);
Related
I'm working on reversing a sentence. I'm able to do it. But I'm not sure, how to reverse the word without changing the special characters positions. I'm using regex but as soon as it finds the special characters it's stopping the reversal of the word.
Following is the code:
Console.WriteLine("Enter:");
string w = Console.ReadLine();
string rw = String.Empty;
String[] arr = w.Split(' ');
var regexItem = new Regex("^[a-zA-Z0-9]*$");
StringBuilder appendString = new StringBuilder();
for (int i = 0; i < arr.Length; i++)
{
char[] chararray = arr[i].ToCharArray();
for (int j = chararray.Length - 1; j >= 0; j--)
{
if (regexItem.IsMatch(rw))
{
rw = appendString.Append(chararray[j]).ToString();
}
}
sb.Append(' ');
}
Console.WriteLine(rw);
Console.ReadLine();
Example : Input
Marshall! Hello.
Expected output
llahsram! olleh.
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);
}
This is a solution without LINQ. I wasn't sure about what are considered special characters.
string sentence = "Marshall! Hello.";
List<string> words = sentence.Split(' ').ToList();
List<string> reversedWords = new List<string>();
foreach (string word in words)
{
char[] arr = new char[word.Length];
for( int i=0; i<word.Length; i++)
{
if(!Char.IsLetterOrDigit((word[i])))
{
for ( int x=0; x< i; x++)
{
arr[x] = arr[x + 1];
}
arr[i] = word[i];
}
else
{
arr[word.Length - 1 - i] = word[i];
}
}
reversedWords.Add(new string(arr));
}
string reversedSentence = string.Join(" ", reversedWords);
Console.WriteLine(reversedSentence);
And this is the output:
Updated Output = llahsraM! olleH.
Here is a non-regex version that does what you want:
var sentence = "Hello, john!";
var parts = sentence.Split(' ');
var reversed = new StringBuilder();
var charPositions = sentence.Select((c, idx) => new { Char = c, Index = idx })
.Where(_ => !char.IsLetterOrDigit(_.Char));
for (int i = 0; i < parts.Length; i++)
{
var chars = parts[i].ToCharArray();
for (int j = chars.Length - 1; j >= 0; j--)
{
if (char.IsLetterOrDigit(chars[j]))
{
reversed.Append(chars[j]);
}
}
}
foreach (var ch in charPositions)
{
reversed.Insert(ch.Index, ch.Char);
}
// olleH, nhoj!
Console.WriteLine(reversed.ToString());
Basically the trick is to remember the position of special (i.e. non letter or digit) characters and insert them at the end to those positions.
This solution is without LINQ and Regex. It may not be an efficient answer but working properly for small string values.
// This will reverse the string and special characters will just stay there.
public string ReverseString(string rString)
{
StringBuilder ss = new StringBuilder(rString);
int y = 0;
// The idea is to swap values. Like swapping first value with last one. It will keep swapping unless it reaches at the middle of the string where no swapping will be needed.
// This first loop is to detect first values.
for(int i=rString.Length-1;i>=0;i--)
{
// This condition is to check if the values is String or not. If it is not string then it is considered as special character which will just stay there at same old position.
if(Char.IsLetter(Convert.ToChar(rString.Substring(i,1))))
{
// This is second loop which is starting from end to swap values from end with first.
for (int k = y; k < rString.Length; k++)
{
// Again checking last values if values are string or not.
if (Char.IsLetter(Convert.ToChar(rString.Substring(k, 1))))
{
// This is swapping. So st1 is First value in that string
// st2 is the last item in that string
char st1 = Convert.ToChar(rString.Substring(k, 1));
char st2 = Convert.ToChar(rString.Substring(i, 1));
//This is swapping. So last item will go to first position and first item will go to last position, To make sure string is reversed.
// Remember when the string value is Special Character, swapping will move forward without swapping.
ss[rString.IndexOf(rString.Substring(i, 1))] = st1;
ss[rString.IndexOf(rString.Substring(k, 1))] = st2;
y++;
// When the swapping is done for first 2 items. The loop will stop to change the values.
break;
}
else
{
// This is just increment if value was Special character.
y++;
}
}
}
}
return ss.ToString();
}
Thanks!
I am new in C# and I am making project but I can't make this delete part ..
If I save my data in .txt file in one line, but contain many fixed length record with no delimiter, if each record has fixed length and each field has fixed length and saved in file like this
1ahly2zamalek
how do I delete, for example the record 2zamalek from line with entering to the program id=2?
public team()
{
Team_ID_Len = 5;
Team_Name_Len = 10;
Team_Rec_Len = 15; ;
Team_ID = new char[Team_ID_Len];
Team_Name = new char[Team_Name_Len];
}
Sounds like you're looking for Substring. Give it a start (length of record * how many), and the length (length of record).
Actually, you might want to create the string as string s = part1+part2 where part1 is the substring from 0 till the start of the record, and part2 is the start of the NEXT record, until the end.
Then just save it.
Your number is your delimiter, split with a char array
using System;
using System;
public static class Program
{
public static void Main()
{
string words = "1sdklfjlsdf2lksjdf3sfd4sfd5fsd6fsd7fsd8fsd9sfd10aslkdfj11jklh12hjk";
int deleteRecordId = 11;
string [] split = words.Split(new Char [] {'1', '2','3','4','5','6','7','8','9','0'});
string newString = "";
int j = 0;
for( int i = 0; i < split.Length; i++)
{
if ( j == deleteRecordId)
{
//ignore this record
Console.WriteLine("ignore i = " + i);
j++;
}
else
{
Console.WriteLine("i = " + i);
if(!( split[i] == ""))
{
newString += j + split[i];
j++;
}
}
}
Console.WriteLine(newString);
}
}
then WriteAll to the file
i have some chars:
chars = "$%##!*abcdefghijklmnopqrstuvwxyz1234567890?;:ABCDEFGHIJKLMNOPQRSTUVWXYZ^&".ToCharArray();
now i'm looking for a method to return a random char from these.
I found a code which maybe can be usefull:
static Random random = new Random();
public static char GetLetter()
{
// This method returns a random lowercase letter
// ... Between 'a' and 'z' inclusize.
int num = random.Next(0, 26); // Zero to 25
char let = (char)('a' + num);
return let;
}
this code returns me a random char form the alphabet but only returns me lower case letters
Well you're nearly there - you want to return a random element from a string, so you just generate a random number in the range of the length of the string:
public static char GetRandomCharacter(string text, Random rng)
{
int index = rng.Next(text.Length);
return text[index];
}
I'd advise against using a static variable of type Random without any locking, by the way - Random isn't thread-safe. See my article on random numbers for more details (and workarounds).
This might work for you:
public static char GetLetter()
{
string chars = "$%##!*abcdefghijklmnopqrstuvwxyz1234567890?;:ABCDEFGHIJKLMNOPQRSTUVWXYZ^&";
Random rand = new Random();
int num = rand.Next(0, chars.Length);
return chars[num];
}
You can use it like;
char[] chars = "$%##!*abcdefghijklmnopqrstuvwxyz1234567890?;:ABCDEFGHIJKLMNOPQRSTUVWXYZ^&".ToCharArray();
Random r = new Random();
int i = r.Next(chars.Length);
Console.WriteLine(chars[i]);
Here is a DEMO.
I had approximate issue and I did it by this way:
public static String GetRandomString()
{
var allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789";
var length = 15;
var chars = new char[length];
var rd = new Random();
for (var i = 0; i < length; i++)
{
chars[i] = allowedChars[rd.Next(0, allowedChars.Length)];
}
return new String(chars);
}
Instead of 26 please use size of your CHARS buffer.
int num = random.Next(0, chars.Length)
Then instead of
let = (char)('a' + num)
use
let = chars[num]
I'm not sure how efficient it is as I'm very new to coding, however, why not just utilize the random number your already creating? Wouldn't this "randomize" an uppercase char as well?
int num = random.Next(0,26);
char let = (num > 13) ? Char.ToUpper((char)('a' + num)) : (char)('a' + num);
Also, if you're looking to take a single letter from your char[], would it be easier to just use a string?
string charRepo = "$%##!*abcdefghijklmnopqrstuvwxyz1234567890?;:ABCDEFGHIJKLMNOPQRSTUVWXYZ^&";
Random rando = new Random();
int ranNum = rando.Next(0, charRepo.Length);
char ranChar = charRepo[ranNum];
private static void Main(string[] args)
{
Console.WriteLine(GetLetters(6));
Console.ReadLine();
}
public static string GetLetters(int numberOfCharsToGenerate)
{
var random = new Random();
char[] chars = "$%##!*abcdefghijklmnopqrstuvwxyz1234567890?;:ABCDEFGHIJKLMNOPQRSTUVWXYZ^&".ToCharArray();
var sb = new StringBuilder();
for (int i = 0; i < numberOfCharsToGenerate; i++)
{
int num = random.Next(0, chars.Length);
sb.Append(chars[num]);
}
return sb.ToString();
}
Your Code is good, you just need to change 'a' to 'A'
static Random random = new Random();
public static char GetLetter()
{
// This method returns a random lowercase letter
// ... Between 'a' and 'z' inclusize.
int num = random.Next(0, 26); // Zero to 25
char let = (char)('A' + num);
return let;
}
This code same as mentioned in the question , just change char let = (char)('A' + num); , it returns upper case letters.
Thanks!!!
I wish This code helps you :
string s = "$%##!*abcdefghijklmnopqrstuvwxyz1234567890?;:ABCDEFGHIJKLMNOPQRSTUVWXYZ^&";
Random random = new Random();
int num = random.Next(0, s.Length -1);
MessageBox.Show(s[num].ToString());
Getting Character from ASCII number:
private string GenerateRandomString()
{
Random rnd = new Random();
string txtRand = string.Empty;
for (int i = 0; i <8; i++) txtRand += ((char)rnd.Next(97, 122)).ToString();
return txtRand;
}
You can try this :
public static string GetPassword()
{
string Characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
Random rnd = new Random();
int index = rnd.Next(0,51);
string char1 = Characters[index].ToString();
return char1;
}
Now you can play with this code block as per your wish. Cheers!
How to delete every 2nd character in a string?
For example:
3030313535333635 -> 00155365
3030303336313435 -> 00036145
3032323437353530 -> 02247550
The strings are always 16-characters long and the result is always 8 characters long - and the character that is being removed is always a '3' - Don't ask why however - I did not dream up this crazy source data.
Try this to get the every other character from the string:-
var s = string.Join<char>("", str.Where((ch, index) => (index % 2) != 0));
String input = "3030313535333635";
String result = "";
for(int i = 1; i < 16; i +=2 )
{
result += input[i];
}
You can use this well-known class System.Runtime.Remoting.Metadata.W3cXsd2001.SoapHexBinary :)
string str = "3030313535333635";
var hex = System.Runtime.Remoting.Metadata.W3cXsd2001.SoapHexBinary.Parse(str);
var newstr = Encoding.ASCII.GetString(hex.Value);
Using a StringBuilder to create a string will save resources
string input = "3030313535333635";
var sb = new StringBuilder(8); // Specify capacity = 8
for (int i = 1; i < 16; i += 2) {
sb.Append(input[i]);
}
string result = sb.ToString();
Code in Java Language
String input= "3030313535333635"
String output="";
for(int i=1;i<input.length();i=i+2)
{
output+=input.charAt(i).toString();
}
System.out.println(output);
Not entirely sure this is possible, but say I have two strings like so:
"IAmAString-00001"
"IAmAString-00023"
What would be a quick'n'easy way to iterate from IAmAString-0001 to IAmAString-00023 by moving up the index of just the numbers on the end?
The problem is a bit more general than that, for example the string I could be dealing could be of any format but the last bunch of chars will always be numbers, so something like Super_Confusing-String#w00t0003 and in that case the last 0003 would be what I'd use to iterate through.
Any ideas?
You can use char.IsDigit:
static void Main(string[] args)
{
var s = "IAmAString-00001";
int index = -1;
for (int i = 0; i < s.Length; i++)
{
if (char.IsDigit(s[i]))
{
index = i;
break;
}
}
if (index == -1)
Console.WriteLine("digits not found");
else
Console.WriteLine("digits: {0}", s.Substring(index));
}
which produces this output:
digits: 00001
string.Format and a for loop should do what you want.
for(int i = 0; i <=23; i++)
{
string.Format("IAmAString-{0:D4}",i);
}
or something close to that (not sitting in front of a compiler).
string start = "IAmAString-00001";
string end = "IAmAString-00023";
// match constant part and ending digits
var matchstart = Regex.Match(start,#"^(.*?)(\d+)$");
int numberstart = int.Parse(matchstart.Groups[2].Value);
var matchend = Regex.Match(end,#"^(.*?)(\d+)$");
int numberend = int.Parse(matchend.Groups[2].Value);
// constant parts must be the same
if (matchstart.Groups[1].Value != matchend.Groups[1].Value)
throw new ArgumentException("");
// create a format string with same number of digits as original
string format = new string('0', matchstart.Groups[2].Length);
for (int ii = numberstart; ii <= numberend; ++ii)
Console.WriteLine(matchstart.Groups[1].Value + ii.ToString(format));
You could use a Regex:
var match=Regex.Match("Super_Confusing-String#w00t0003",#"(?<=(^.*\D)|^)\d+$");
if(match.Success)
{
var val=int.Parse(match.Value);
Console.WriteLine(val);
}
To answer more specifically, you could use named groups to extract what you need:
var match=Regex.Match(
"Super_Confusing-String#w00t0003",
#"(?<prefix>(^.*\D)|^)(?<digits>\d+)$");
if(match.Success)
{
var prefix=match.Groups["prefix"].Value;
Console.WriteLine(prefix);
var val=int.Parse(match.Groups["digits"].Value);
Console.WriteLine(val);
}
If you can assume that the last 5 characters are the number then:
string prefix = "myprefix-";
for (int i=1; i <=23; i++)
{
Console.WriteLine(myPrefix+i.ToString("D5"));
}
This function will find the trailing number.
private int FindTrailingNumber(string str)
{
string numString = "";
int numTest;
for (int i = str.Length - 1; i > 0; i--)
{
char c = str[i];
if (int.TryParse(c.ToString(), out numTest))
{
numString = c + numString;
}
}
return int.Parse(numString);
}
Assuming all your base strings are the same, this would iterate between strings.
string s1 = "asdf123";
string s2 = "asdf127";
int num1 = FindTrailingNumber(s1);
int num2 = FindTrailingNumber(s2);
string strBase = s1.Replace(num1.ToString(), "");
for (int i = num1; i <= num2; i++)
{
Console.WriteLine(strBase + i.ToString());
}
I think it would be better if you do the search from the last (Rick already upvoted you since it was ur logic :-))
static void Main(string[] args)
{
var s = "IAmAString-00001";
int index = -1;
for (int i = s.Length - 1; i >=0; i--)
{
if (!char.IsDigit(s[i]))
{
index = i;
break;
}
}
if (index == -1)
Console.WriteLine("digits not found");
else
Console.WriteLine("digits: {0}", s.Substring(index));
Console.ReadKey();
}
HTH
If the last X numbers are always digits, then:
int x = 5;
string s = "IAmAString-00001";
int num = int.Parse(s.Substring(s.Length - x, x));
Console.WriteLine("Your Number is: {0}", num);
If the last digits can be 3, 4, or 5 in length, then you will need a little more logic:
int x = 0;
string s = "IAmAString-00001";
foreach (char c in s.Reverse())//Use Reverse() so you start with digits only.
{
if(char.IsDigit(c) == false)
break;//If we start hitting non-digit characters, then exit the loop.
++x;
}
int num = int.Parse(s.Substring(s.Length - x, x));
Console.WriteLine("Your Number is: {0}", num);
I'm not good with complicated RegEx. Because of this, I always shy away from it when maximum optimization is unnecessary. The reason for this is RegEx doesn't always parse strings the way you expect it to. If there is and alternate solution that will still run fast then I'd rather go that route as it's easier for me to understand and know that it will work with any combination of strings.
For Example: if you use some of the other solutions presented here with a string like "I2AmAString-000001", then you will get "2000001" as your number instead of "1".