Using a hand-made code, this is suppose to make the user's input encoded into something different (the letter right after the letter they typed). Whenever I try to run it, the returns are only the user's sentence. I'm happy it works for the decoder, but the encoder needs to encode the message. I'm wondering why it's not working.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EncoderDecoder
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Please enter a sentence. No numbers, smybols, or punctuations.");
string sentence = Console.ReadLine();
Console.WriteLine();
Console.WriteLine("Your encoded message.");
string encodedSentence = Encode(sentence);
Console.WriteLine(encodedSentence);
Console.WriteLine("Your decoded message. Also known as your original message.");
string decodedSentence = Decode(sentence);
Console.WriteLine(decodedSentence);
Console.ReadLine();
}
private static string Decode(string encodedSentence)
{
char[] wordArray;
string[] words = encodedSentence.Split(' ');
for (int i = 0; i > words.Length; i++)
{
wordArray = words[i].ToArray();
if (wordArray.Length > 1)
{
char beginLetter = wordArray[0];
wordArray[0] = wordArray[wordArray.Length + 1];
wordArray[wordArray.Length + 1] = beginLetter;
}
for (int t = 0; t < wordArray.Length; t++)
{
wordArray[t] = (char)(wordArray[t] + 1);
}
words[i] = new string(wordArray);
}
string decoded = string.Join(" ", words);
return decoded;
}
private static string Encode(string sentence)
{
char[] wordArray;
string[] words = sentence.Split(' ');
for (int i = 0; i > words.Length; i++)
{
wordArray = words[i].ToArray();
if (wordArray.Length > 1)
{
char beginLetter = wordArray[0];
wordArray[0] = wordArray[wordArray.Length - 1];
wordArray[wordArray.Length - 1] = beginLetter;
}
for(int t = 0; t > wordArray.Length; t++)
{
wordArray[t] = (char)(wordArray[t] + 1);
}
words[i] = new string(wordArray);
}
string encoded = string.Join(" ", words);
return encoded;
}
}
}
Using the arrays, I split the string into the array and then use that array to individually alter the letters. For some reason it's not working...
Both for's are wrong, try: for (int i = 0; i < words.Length; i++)
In the encoder in your for loop you've got where t > word array.length should this be less than
Related
I'm preparing for my interview, faced the problem with the task. The case is that we're having a string:
test12pop90java989python
I need to return new string where words will be reversed and numbers will stay in the same place:
test12pop90java989python ==> tset12pop90avaj989nohtyp
What I started with:
Transferring string to char array
Use for loop + Char.IsNumber
??
var charArray = test.ToCharArray();
for (int i = 0; i < charArray.Length; i++)
{
if (!Char.IsNumber(charArray[i]))
{
....
}
}
but currently I'm stuck and don't know how to proceed, any tips how it can be done?
You can't reverse a run of letters until you've observed the entire run; until then, you need to keep track of the pending letters to be reversed and appended to the final output upon encountering a number or the end of the string. By storing these pending characters in a Stack<> they are naturally returned in the reverse order they were added.
static string Transform(string input)
{
StringBuilder outputBuilder = new StringBuilder(input.Length);
Stack<char> pending = new Stack<char>();
foreach (char c in input)
if (char.IsNumber(c))
{
// In the reverse order of which they were added, consume
// and append pending characters as long as they are available
while (pending.Count > 0)
outputBuilder.Append(pending.Pop());
// Alternatively...
//foreach (char p in pending)
// outputBuilder.Append(p);
//pending.Clear();
outputBuilder.Append(c);
}
else
pending.Push(c);
// Handle pending characters when input does not end with a number
while (pending.Count > 0)
outputBuilder.Append(pending.Pop());
return outputBuilder.ToString();
}
A similar but buffer-free way is to do it is to store the index of the start of the current run of letters, then walk back through and append each character when a number is found...
static string Transform(string input)
{
StringBuilder outputBuilder = new StringBuilder(input.Length);
int lettersStartIndex = -1;
for (int i = 0; i < input.Length; i++)
{
char c = input[i];
if (char.IsNumber(c))
{
if (lettersStartIndex >= 0)
{
// Iterate backwards from the previous character to the start of the run
for (int j = i - 1; j >= lettersStartIndex; j--)
outputBuilder.Append(input[j]);
lettersStartIndex = -1;
}
outputBuilder.Append(c);
}
else if (lettersStartIndex < 0)
lettersStartIndex = i;
}
// Handle remaining characters when input does not end with a number
if (lettersStartIndex >= 0)
for (int j = input.Length - 1; j >= lettersStartIndex; j--)
outputBuilder.Append(input[j]);
return outputBuilder.ToString();
}
For both implementations, calling Transform() with...
string[] inputs = new string[] {
"test12pop90java989python",
"123test12pop90java989python321",
"This text contains no numbers",
"1a2b3c"
};
for (int i = 0; i < inputs.Length; i++)
{
string input = inputs[i];
string output = Transform(input);
Console.WriteLine($" Input[{i}]: \"{input }\"");
Console.WriteLine($"Output[{i}]: \"{output}\"");
Console.WriteLine();
}
...produces this output...
Input[0]: "test12pop90java989python"
Output[0]: "tset12pop90avaj989nohtyp"
Input[1]: "123test12pop90java989python321"
Output[1]: "123tset12pop90avaj989nohtyp321"
Input[2]: "This text contains no numbers"
Output[2]: "srebmun on sniatnoc txet sihT"
Input[3]: "1a2b3c"
Output[3]: "1a2b3c"
A possible solution using Regex and Linq:
using System;
using System.Text.RegularExpressions;
using System.Linq;
public class Program
{
public static void Main()
{
var result = "";
var matchList = Regex.Matches("test12pop90java989python", "([a-zA-Z]*)(\\d*)");
var list = matchList.Cast<Match>().SelectMany(o =>o.Groups.Cast<Capture>().Skip(1).Select(c => c.Value));
foreach (var el in list)
{
if (el.All(char.IsDigit))
{
result += el;
}
else
{
result += new string(el.Reverse().ToArray());
}
}
Console.WriteLine(result);
}
}
I've used code from stackoverflow.com/a/21123574/1037948 to create a list of Regex matches on line 11:
var list = matchList.Cast<Match>().SelectMany(o =>o.Groups.Cast<Capture>().Skip(1).Select(c => c.Value));
Hey you can do something like:
string test = "test12pop90java989python", tempStr = "", finalstr = "";
var charArray = test.ToCharArray();
for (int i = 0; i < charArray.Length; i++)
{
if (!Char.IsNumber(charArray[i]))
{
tempStr += charArray[i];
}
else
{
char[] ReverseString = tempStr.Reverse().ToArray();
foreach (char charItem in ReverseString)
{
finalstr += charItem;
}
tempStr = "";
finalstr += charArray[i];
}
}
if(tempStr != "" && tempStr != null)
{
char[] ReverseString = tempStr.Reverse().ToArray();
foreach (char charItem in ReverseString)
{
finalstr += charItem;
}
tempStr = "";
}
I hope this helps
I am trying to see weather the string is in alphabetical order or no and this error pops up
System.ArgumentOutOfRangeException: Index and length must refer to a location within the string.
Parameter name: length
at System.String.Substring(Int32 startIndex, Int32 length)
at Rextester.Program.Main(String[] args)**
public static void Main(string[] args)
{
string str = "bat\ncat\ndog\n";
int c = 0;
for (int i = 0; i < str.Length; i++)
{
if ((str.Substring(i,i + 1).Equals("\n")))
{
c++;
}
}
String[] strArray = new String[c + 1]; //declare with size
int g = 0;
String h = "";
for (int i = 0; i < str.Length; i++)
{
if ((str.Substring(i,i + 1).Equals("\n")))
{
strArray[g] = h;
h = "";
g = g + 1;
}
else
{
h = h + str.Substring(i,i + 1);
}
}
String p = "True";
for (int i = 0; i < g; i++)
{
if (i < (g - 1))
{
String f = strArray[i];
String g2 = strArray[i + 1];
char d = f[0];
char s = g2[0];
int d1 = (int)d;
int s1 = (int)s;
if (d1 > s1)
{
p = "False";
}
}
}
Console.WriteLine(p);
}
}
Not sure about what you are doing in your second loop and why is it so complex. We can do the same like this. Hope this helps.
using System;
public class Program
{
public static void Main()
{
string str = "abcd";
str = str.Replace('\n',' ');
String p = "True";
for (int i = 1; i < str.Length; i++) {
// if element at index 'i' is less
// than the element at index 'i-1'
// then the string is not sorted
if (str[i] < str[i - 1]) {
p = "false";
}
}
Console.WriteLine(p);
}
}
Pay attention to the definition of substring
The substring starts at a specified character position and has a
specified length
Considering your first use of substring, here
for (int i = 0; i < str.Length; i++)
{
if (str.Substring(i, i + 1).Equals("\n"))
{
c++;
}
}
What happens when we get to i=6 here? Substring tries to give you a new string that starts at position i = 6, and is length = 7 characters long. So it tries to give you 7 characters starting from str[6] to str[12]. Well, there is no str[12], so you get an exception.
Its clear that your intent is NOT to get a string that starts at position 6 and is 7 characters long. You want ONE character, so your loop should be this
for (int i = 0; i < str.Length; i++)
{
if (str.Substring(i, 1).Equals("\n"))
{
c++;
}
}
But theres a much simpler way to get your words in alphabetical order using LINQ
string str = "bat\ncat\ndog\n";
//Removes the trailing \n so you don't have one entry that is only whitespace
str = str.Trim();
string[] strSplit = str.Split('\n').OrderBy(x => x[0]).ToArray();
Now all substrings are sorted alphabetically and you can do whatever you want with them
As much as I tried to find a similar version in the question here, I couldn't find something.. so I am asking your help.
After reading some numbers from a textfile (now in string format), I split them in rows and columns and add them to a 2d-array (in string format as well). Now I want to convert everythinh in integers so that I can play with sorting the numbers out later.
Here is my code...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace ArrayProgram
{
class Program
{
int number = 0;
int i = 0;
int k = 0;
string strnum;
public void onetohundredints()
{
StreamWriter writer = new StreamWriter("numberstored.txt");
for (i = 0; i < 10; i++)
{
for (k = 0; k < 10; k++)
{
number++;
Console.Write(number + " ");
strnum = number.ToString();
writer.Write(strnum + " ");
}
Console.WriteLine();
writer.WriteLine();
}
writer.Close();
}
public void readints()
{
StreamReader reader = new StreamReader("numberstored.txt");
string data = reader.ReadToEnd();
reader.Close();
string[,] dataarray = new string[10,10];
int[] numbers = new int[100];
string[] dataperlines = data.Split(new[] { '\r','\n' },StringSplitOptions.RemoveEmptyEntries);
for(int i=0; i<=dataperlines.Count()-1; i++)
{
string[] numbersperrow = dataperlines[i].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
for (int j=0; j<=numbersperrow.Count()-1; j++)
{
dataarray[i, j] = numbersperrow[j];
}
}
}
public static void Main(string[] args)
{
Program prog = new Program();
prog.onetohundredints();
prog.readints();
Console.ReadKey();
}
}
}
After I insert the number into the 2d-array, how do I convert all of it in integers?
If you don't have a particular reason to have an array of strings, you can just save you data as int in the first place. Just change your inner for loop to do:
var parsed = int.TryParse(numbersperrow[j], out dataarray[i, j]);
if (!parsed)
{
// Error
}
While that should work, I would suggest to re-write your ReadData method to look similar to the sample below.
public int[,] ReadData(string filePath, int xDimension, int yDimension)
{
var results = new int[xDimension, yDimension];
var lines = File.ReadLines(filePath);
for (var i = 0; i < allLines.Count(); i++)
{
var values = lines[i].Split(new[] { ' ' },
StringSplitOptions.RemoveEmptyEntries);
for (var j = 0; j < values.Count(); j++)
{
var parsed = int.TryParse(values[j], out results[i, j]);
if (!parsed) { }
}
}
return results;
}
You're putting everything into a string array. That array can only hold strings, not numbers. If you want to make the 2d array hold numbers, define it as int[,] dataarray = new int[10,10]; Next, in the final loop, simply do dataarray[i, j] = Convert.ToInt32(numbersperrow[j]);
Edit: You can use int.TryParse(numbersperrow[j], out value) if you aren't sure that numbersperrow[j] will be a number. Value will return false if the conversion is not successful.
I am happy to say that both solutions work. I now have my numbers in my 2d array. But now I wish to play with them. Let's say that I want the numbers printed on the screen in reverse order.
Having this correct solution:
int numbers;
int[,] dataarray = new int[10,10];
string[] dataperlines = data.Split(new[] { '\r','\n' },StringSplitOptions.RemoveEmptyEntries);
for(int i=0; i<=dataperlines.Count()-1; i++)
{
string[] numbersperrow = dataperlines[i].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
for (int j=0; j<=numbersperrow.Count()-1; j++)
{
numbers = int.Parse(numbersperrow[j]);
dataarray[i, j] = numbers;
Console.Write(numbers + " ");
}
Console.WriteLine();
}
I know that I have to make a double for loop. But how do I write a succesful syntax for the numbers to be printed properly?
I also tried this:
int[,] reversedarray = new int[10, 10];
reversedarray[i, j] = Array.Reverse(dataarray[i,j]);
but the dataarray[i,j] becomes red and the error "cannot convert from int to system.Array occurs... what am I missing?
I also tried this...
for (i = 10; i <= dataperlines.Count(); i--)
{
string[] numbersperrow = dataperlines[i].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
for (j =10; j <= numbersperrow.Count(); j--)
{
numbers = int.Parse(numbersperrow[j]);
reversedarray[i, j] = numbers;
Console.Write(numbers + " ");
}
Console.WriteLine();
}
But I have an IndexOutOfRange exception coming from
string[] numbersperrow = dataperlines[i].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
I understood that since I splitted the columns into rows too, it is unecessary to write it again, but I am stuck. I tried simplifying the code since I have my 2darray with its elements and I my tries were fallacious. Any more suggestions?
I am a beginner in C# and i am trying to make a "hangman" game. I got stuck at the process when the player guess a letter.
If the word for example is DATA, the application only gets the first A in DATA.
I understand that i have to loop the word to get all the A´s but i am having touble with making it work!
here is my code for the method myGuess:
public void myGuess(String letter)
{
int plats = 0;
string wordToGuess = label4.Text;
plats = wordToGuess.IndexOf(letter);
string wordToShow = label5.Text;
//ersätt "_" med bokstaven på alla positioner bokstaven dyker upp
wordToShow = wordToShow.Substring(0, wordToGuess.IndexOf(letter)) + letter +
wordToShow.Substring(plats + 1, wordToShow.Length - (plats + 1));
label5.Text = wordToShow;
}
I have been trying to google it but because i am a beginner i don't understand the
suggestions people give. Hopefully it is a way to loop for more than one letter with IndexOf?
IndexOf returns the index of the first instance of the character in the string. You could manipulate your string using substring, but you'd be making it more complicated than you need to need. Instead, you can just loop through each of the characters in the String with a for loop:
for (int i = 0; i < wordToGuess.Length; i++ )
{
if (WordToGuess[i] == letter)
{
//Update the correctly guessed letters, (using value of i to determine which letter to make visible.)
}
}
label5.Text = wordToShow;
You can use this:
label4(wordToGuess): DATA
label5(wordToShow): ****
When you call myGuess('A')
label4(wordToGuess): DATA
label5(wordToShow): *A*A
When you call myGuess('T')
label4(wordToGuess): DATA
label5(wordToShow): *ATA
...
public void myGuess(char letter)
{
string wordToGuess = label4.Text;
string wordToShow = label5.Text;
if (wordToShow.Length == 0)
{
for (int i = 0; i < wordToGuess.Length; i++)
wordToShow += "*";
}
for (int i = 0; i < wordToGuess.Length; i++)
{
if (wordToGuess[i] == letter || wordToGuess[i] == wordToShow[i])
wordToShow = wordToShow.Remove(i,1).Insert(i, Char.ToString(letter));
}
label5.Text = wordToShow;
}
Here's a long solution that's probably overly generic.
List<int> findIndexes(string myStr, char letter)
{
var foundIndexes = new List<int>();
for (int i = 0; i < myStr.Length; i++)
{
if (myStr[i] == letter)
foundIndexes.Add(i);
}
return foundIndexes;
}
string ReplaceIndex(string s, int index, char letter){
return s.Substring(0, index )
+ letter
+ s.Substring(index + 1, s.Length - (index + 1));
}
void Main()
{
string s= "data";
string wordToShow = "____";
var letter = 'a';
var indexes = findIndexes(s, letter);
foreach (var index in indexes)
{
wordToShow = ReplaceIndex(wordToShow, index, letter);
}
Console.WriteLine (wordToShow);
}
A simple for loop should handle it.
for (int i = 0; i < wordToGuess.Length; i++)
{
if (wordToGuess[i].ToString().Equals(letter.ToString(), System.StringComparison.InvariantCultureIgnoreCase))
{
wordToShow = string.Format("{0}{1}{2}", wordToShow.Substring(0, i), letter, wordToShow.Substring(i, wordToShow.Length - (i + 1)));
}
}
Here's a fiddle: http://dotnetfiddle.net/UATeVJ
I want to split a long string which looks something like this
weygjjsgdgkweygwjiewlewegygciefewjknfkeuwyfjkdygwfsn
into
"weygjjsgdgk"
"weygwjiewle"
"wegygciefew"
"jknfkeuwyfj"
"kdygwfsn"
in chunks of 10 chars...and format it like "" outside...how can I do this?
Regex Approach
string instr = "weygjjsgdgkweygwjiewlewegygciefewjknfkeuwyfjkdygwfsn";
string results = Regex.Replace(instr, "(.{1,11})", "\"$1\"\n");
Console.WriteLine(results);
Results
"weygjjsgdgk"
"weygwjiewle"
"wegygciefew"
"jknfkeuwyfj"
"kdygwfsn"
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string input = "012345678901234567890";
int remaining = input.Length;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < input.Length; i+=10)
{
sb.Append('"').Append(input.Substring(i, Math.Min(10, remaining))).Append('"');
remaining -= 10;
}
Console.WriteLine(sb.ToString());
}
}
}
Just one more method:
private static string[] SplitBy(string source, int count)
{
const string Separator = "╩";
var byCount = source.Select((c, i) => i % count == 0 ? Separator + c : c.ToString()).ToArray();
var inString = string.Join(string.Empty, byCount);
return inString.Split(new[] { Separator }, StringSplitOptions.RemoveEmptyEntries);
}
Use example:
var splitted = SplitBy("some very long str", 5);
Result:
some
very
long
str
You can use the Substring methods, Substring(int startIndex, int length) and Substring(int startIndex). I've hardly done any C#, but I think it would look something like this:
string originalString = "weygjjsgdgkweygwjiewlewegygciefewjknfkeuwyfjkdygwfsn";
string newString = "";
while (originalString.Length > 10) {
string line = originalString.Substring(0, 10);
newString = "\"" + line + "\"\n";
originalString = originalString.Substring(10);
}
newString = "\"" + originalString + "\"\n";
string input = "...";
IEnumerable<string> output =
from i in Enumerable.Range(0, (input.Length + 1) / 10)
let start = i * 10
let length = Math.Min(10, input.Length - start)
select "\"" + input.Substring(start, length) + "\""
Maybe slightly faster approach - should be faster for longer strings.
static void Main(string[] args)
{
string input = "012345678901234567890";
// Create a StringBuilder with enough space
StringBuilder sb = new StringBuilder(input.Length + input.Length / 10 * 3 + 3);
sb.Append('"');
for (int n = 0; n < input.Length; n++)
{
// don't add if this is the first char
if (n > 0 && n % 10 == 0)
{
sb.Append("\"\n\"");
}
sb.Append(input[n]);
}
sb.Append('"');
Console.WriteLine(sb.ToString());
}
foreach(var text in "abcdefghijklmnopqrstuvwxyz".SplitString(5))
{
Debug.WriteLine(text);
}
public static IEnumerable<string> SplitString(this string input, int outputStringLength)
{
var count = 0;
while (count < input.Length)
{
var length = Math.Min(outputStringLength, input.Length - count);
yield return string.Format("\"{0}\"", input.Substring(count, length));
count += outputStringLength;
}
}