I have a list of items, each with numbers, followed by a space, and then a word. Think scrabble.
36 adore
36 adore
27 amigo
31 amino
28 amiss
I am trying to use the 2 digit number as an organizational item to which I can rank the words by order of value.
My list, ComJoined is shown above.
My Code is:
for (int i = 0; i < ComJoined.Count; i++)
{
if (i + 1 <= ComJoined.Count)
{
int one = (Convert.ToInt32(ComJoined[i].Substring(0, 2)));
int two = Convert.ToInt32(ComJoined[i + 1].Substring(0, 2));
if (one <= two)
{
string Stuff = ComJoined[i];
ComJoined.Insert(i + 1, Stuff);
ComJoined.RemoveAt(i);
}
}
}
For some reason it says that "Input string was not in a correct format." I read that this meant the string didn't have a int value, but the part being converted, the first two digits, obviously do. Why is this occurring?
So you want to sort the list descending, according to the 2 digit code, and all items start with the two digit code?
This would just be a linq one-liner: var sortedList = ComJoined.OrderByDescending().ToList()
This might be less complex of a solution to your problem:
var words = new SortedDictionary<int, string>();
foreach (var com in ComJoined)
{
string[] splitCom = com.Split(' ');
// Assuming your data is in the correct format. You could use TryParse to avoid an exception.
words.Add(int.Parse(splitCom[0]), splitCom[1]);
}
// Do something with the sorted dictionary...
foreach (KeyValuePair<int, string> word in words)
Console.WriteLine("{0} {1}", word.Key, word.Value);
Related
My input is a string of integers, which I have to check whether they are even and display them on the console, if they are. The problem is that what I wrote checks only the individual digits and not the numbers.
string even = "";
while (true)
{
string inputData = Console.ReadLine();
if (inputData.Equals("x", StringComparison.OrdinalIgnoreCase))
{
break;
}
for (int i = 0; i < inputData.Length; i++)
{
if (inputData[i] % 2 == 0)
{
even +=inputData[i];
}
}
}
foreach (var e in even)
Console.WriteLine(e);
bool something = string.IsNullOrEmpty(even);
if( something == true)
{
Console.WriteLine("N/A");
}
For example, if the input is:
12
34
56
my output is going to be
2
4
6 (every number needs to be displayed on a new line).
What am I doing wrong? Any help is appreciated.
Use string.Split to get the independent sections and then int.TryParse to check if it is a number (check Parse v. TryParse). Then take only even numbers:
var evenNumbers = new List<int>();
foreach(var s in inputData.Split(" "))
{
if(int.TryParse(s, out var num) && num % 2 == 0)
evenNumbers.Add(num); // If can't use collections: Console.WriteLine(num);
}
(notice the use of out vars introduced in C# 7.0)
If you can use linq then similar to this answer:
var evenNumbers = inputData.Split(" ")
.Select(s => (int.TryParse(s, out var value), value))
.Where(pair => pair.Item1)
.Select(pair => pair.value);
I think you do too many things here at once. Instead of already checking if the number is even, it is better to solve one problem at a time.
First we can make substrings by splitting the string into "words". Net we convert every substring to an int, and finally we filter on even numbers, like:
var words = inputData.Split(' '); # split the words by a space
var intwords = words.Select(int.Parse); # convert these to ints
var evenwords = intwords.Where(x => x % 2 == 0); # check if these are even
foreach(var even in evenwords) { # print the even numbers
Console.WriteLine(even);
}
Here it can still happen that some "words" are not integers, for example "12 foo 34". So you will need to implement some extra filtering between splitting and converting.
I want to easily pre-populate a single dimensional string array which I am calling "letters" with the values:
AAAAAA
AAAAAB
AAAAAC
AAAAAD
..
..
ZZZZZX
ZZZZZY
ZZZZZZ
Thats 165 million combinations in order.
The idea being I need to then be able to ask for any particular combination of 6 characters such as BBCHHJ and use Array.Index to return the element of the array it is in.
I have the second bit fine:
String searchFor;
Console.Write("Enter a string value to search for: ");
searchFor = Console.ReadLine();
int indexValue = Array.IndexOf(letters, searchFor);
Console.WriteLine("The value you are after is in element index: " + indexValue);
Console.ReadLine();
But I have no idea how to easily initialise the letters array with all those combinations, in order!
A variation on Jakub's answer which should be a bit more efficient:
int result = s
.Select(c => c - 'A') // map 'A'-'Z' to 0-25
.Aggregate(0, (total, next) => total * 26 + next); // calculate the base 26 value
This has the advantage of avoiding the Reverse and the separate Sum, and the powers of 26 don't have to be calculated from scratch in each iteration.
Storing 308 million elements in array and searching them is not the best solution, rather calculate the index at runtime. I have created a code sample:
string input = "ZZZZZZ";
//default values
string alphabets_s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char[] alphabets = alphabets_s.ToCharArray();
int result = 1; //starting with "one" because zero will make everything zero
//calculating index
for (int i = 0; i < input.Length; i++)
{
//get character index and add "1" to avoid multiplication with "0"
int index = Array.IndexOf(alphabets, input[i]) + 1;
//multiply it with the current result
result *= index;
}
//subtract 1 from final result, because we started it with 1
result--;
PS: I did just basic testing, please inform me if you find anything wrong in it.
As I wrote in a comment, what you're trying to achieve is basically conversion from base 26 number.
The first step is to convert the string to a list of digits. Then just multiply by powers of 26 and add together:
var s = "AAAABB";
var result = s
.Select(c => c - 'A') //map characters to numbers: A -> 0, B -> 1 etc
.Reverse() //reverse the sequence to have the least significant digit first
.Select((d, i) => d * Math.Pow(26, i))
.Sum();
This is the question:
Write a program that reads a string from the console and prints in alphabetical order all letters from the input string and how many times each one of them occurs in the string.
It seemed interesting and not too complicated at first, but I couldn't solve it.
public static void Letters()
{
string input;
Console.Write("Enter a string: ");
input = Console.ReadLine();
var chars = new List<char>();
//To populate characters with the letters of the input but without repetition
for(int index = 0; index < input.Length; index++)
{
if(!characters.Contains(input[index]))
characters.Add(input[index]);
}
//To increment the counter corresponding to the character index
int[] counter = new int[characters.Count];
//Now what ?!
}
My thinking is:
I create a collection to hold the letters of the input string, without any repetition.
Then I use an int array of the same size such that each int holds the number of times the corresponding letter has occurred in the input string.
I not only don't know how to implement this, but I have a feeling its not an ideal solution
to the problem. There's probably a query or a lambda expression that should make this easy
to implement and read.
Note: The question following this is of the same nature. The difference is that it asks
to replace the repeated letters with a single one "aaabbbccc" to "abc".
I will appreciate if the logic is described. I will try to implement it on my own,
just point me to the logic.
EDIT:
This my answer using a dictionary
public static void Letters()
{
string input;
Console.Write("Enter a string: ");
input = Console.ReadLine();
var dict = new Dictionary<char, int>();
for(int index = 0; index < input.Length; index++)
{
char theKey = input[index]; //just for clarity
if(!dict.ContainsKey(theKey))
dict.Add(theKey, 1);
else
dict[input[index]]++;
}
foreach(var key in dict.Keys)
{
Console.WriteLine("{0}\t{1}", key, dict[key]);
}
Dictionnary<String, int>
Key = string = letter IE a,b,c,d,e,f.....
Int is number of occurence
So start by doing this :
Dictionnary.add(a,0)
...
Dictionnary.add(z,0);
And then read the string and do this
Dictionnary[letterFound ] += 1;
There is a better way knowing what is the value in ASCi of each letter to init the dictionnary, but i don't think is mandatory for such exercice.
Good luck
var myString = "Hello";
var dict = new Dictionary<char, int>();
foreach(var c in myString)
{
if(!dict.ContainsKey(c))
dict.Add(c, 1);
else
dict[c]++;
}
var orderedDict = dict.OrderBy(x => x.Key);
foreach(var kvp in orderedDict)
{
Console.WriteLine("Letter: {0}, Times: {1}", kvp.Key, kvp.Value);
}
For simple and readable solution use LINQ, GroupBy and anonymous types
string input = Console.ReadLine();
var groupedLettersOrdered = input.GroupBy(x => x, (character, charCollection) =>
new {Character = character, Count = charCollection.Count()})
.OrderBy(x => x.Character);
foreach(var letterGroup in groupedLettersOrdered)
Console.WriteLine("Character {0}, Count: {1}", letterGroup.Character, letterGroup.Count);
However Dictionary<char, int> solution will be (should be) faster and better for large strings
Consider first that a character has a binary representation (sequence of 1s and 0s) just like a scalar value. Consider also that for a Latin alphabet like English, the alphabetical order and numerical order of their equivalents correspond.
So... you could do something like this:
define an array of ints of a size large enough to accommodate all possible character values (arbitrarily, we could make it 256 for a UTF-8 string).
iterate over each character in the string; for each character, convert the character to its integer equivalent, use that as an index into the array and increment the value at that index.
iterate over the array and for each non-zero element, print out the character equivalent of the array index and the contents of the element (character count)
string myString = "the quick brown fox jumps over the lazy dog";
byte[] bytes = Encoding.UTF8.GetBytes(myString);
int[] counts = new int[256];
foreach (var b in bytes)
{
counts[(int)b]++;
}
for (int i = 0; i < 256; i++)
{
if (counts[i] > 0)
{
Console.WriteLine("{0} - {1}", (char)(byte)i, counts[i]);
}
}
The above solution can easily be generalized to disregard case by performing GetBytes on myString.ToUpper(). To generalize to Unicode would be a little more work because you'd have to pair up the bytes in proper endian order.
I'm currently making a game but I seem to have problems reading values from a text file. For some reason, when I read the value, it gives me the ASCII code of the value rather than the actual value itself when I wrote it to the file. I've tried about every ASCII conversion function and string conversion function, but I just can't seem to figure it out.
I use a 2D array of integers. I use a nested for loop to write each element into the file. I've looked at the file and the values are correct, but I don't understand why it's returning the ASCII code. Here's the code I'm using to write and read to file:
Writing to file:
for (int i = 0; i < level.MaxRows(); i++)
{
for (int j = 0; j < level.MaxCols(); j++)
{
fileWrite.Write(level.GetValueAtIndex(i, j) + " ");
//Console.WriteLine(level.GetValueAtIndex(i, j));
}
//add new line
fileWrite.WriteLine();
}
And here's the code where I read the values from the file:
string str = "";
int iter = 0; //used to iterate in each column of array
for (int i = 0; i < level.MaxRows(); i++)
{
iter = 0;
//TODO: For some reason, the file is returning ASCII code, convert to int
//keep reading characters until a space is reached.
str = fileRead.ReadLine();
//take the above string and extract the values from it.
//Place each value in the level.
foreach (char id in str)
{
if (id != ' ')
{
//convert id to an int
num = (int)id;
level.ChangeTile(i, iter, num);
iter++;
}
}
This is the latest version of the loop that I use to read the values. Reading other values is fine; it's just when I get to the array, things go wrong. I guess my question is, why did the conversion to ASCII happen? If I can figure that out, then I might be able to solve the issue. I'm using XNA 4 to make my game.
This is where the convertion to ascii is happening:
fileWrite.Write(level.GetValueAtIndex(i, j) + " ");
The + operator implicitly converts the integer returned by GetValueAtIndex into a string, because you are adding it to a string (really, what did you expect to happen?)
Furthermore, the ReadLine method returns a String, so I am not sure why you'd expect a numeric value to magically come back here. If you want to write binary data, look into BinaryWriter
This is where you are converting the characters to character codes:
num = (int)id;
The id variable is a char, and casting that to int gives you the character code, not the numeric value.
Also, this converts a single character, not a whole number. If you for example have "12 34 56 " in your text file, it will get the codes for 1, 2, 3, 4, 5 and 6, not 12, 34 and 56.
You would want to split the line on spaces, and parse each substring:
foreach (string id in str.Split(' ')) {
if (id.Length > 0) {
num = Int32.Parse(id);
level.ChangeTile(i, iter, num);
iter++;
}
}
Update: I've kept the old code (below) with the assumption that one record was on each line, but I've also added a different way of doing it that should work with multiple integers on a line, separated by a space.
Multiple records on one line
str = fileRead.ReadLine();
string[] values = str.Split(new Char[] {' '});
foreach (string value in values)
{
int testNum;
if (Int32.TryParse(str, out testnum))
{
// again, not sure how you're using iter here
level.ChangeTile(i, iter, num);
}
}
One record per line
str = fileRead.ReadLine();
int testNum;
if (Int32.TryParse(str, out testnum))
{
// however, I'm not sure how you're using iter here; if it's related to
// parsing the string, you'll probably need to do something else
level.ChangeTile(i, iter, num);
}
Please note that the above should work if you write out each integer line-by-line (i.e. how you were doing it via the WriteLine which you remarked out in your code above). If you switch back to using a WriteLine, this should work.
You have:
foreach (char id in str)
{
//convert id to an int
num = (int)id;
A char is an ASCII code (or can be considered as such; technically it is a unicode code-point, but that is broadly comparable assuming you are writing ANSI or low-value UTF-8).
What you want is:
num = (int)(id - '0');
This:
fileWrite.Write(level.GetValueAtIndex(i, j) + " ");
converts the int returned from level.GetValueAtIndex(i, j) into a string. Assuming the function returns the value 5 for a particular i and j then you write "5 " into the file.
When you then read it is being read as a string which consists of chars and you get the ASCII code of 5 when you cast it simply to an int. What you need is:
foreach (char id in str)
{
if (id != ' ')
{
//convert id to an int
num = (int)(id - '0'); // subtract the ASCII value for 0 from your current id
level.ChangeTile(i, iter, num);
iter++;
}
}
However this only works if you only ever are going to have single digit integers (only 0 - 9). This might be better:
foreach (var cell in fileRead.ReadLine().Split(' '))
{
num = Int.Parse(cell);
level.ChangeTile(i, iter, num);
iter++;
}
Hi I want to find all the different combinations rather linear selections of characters from a given string without losing sequence as units of different sizes. Example:
Lets say a word "HAVING"
Then it can have combinations like (spaces separating individual units).
HA VI N G
HAV ING
H AV I N G
HAVIN G
H AVING
H AVIN G
HA VING
H AVI NG
....
Like this all the different selections of units of different lengths.
Can someone give a prototype code or algo idea.
Thanks,
Kalyana
In a string of size n, you have n-1 positions where you could place spaces (= between each pair of consecutive letters). Thus, you have 2^(n-1) options, each represented by a binary number with n-1 digits, e.g., your first example would be 01011.
That should give you enough information to get started (no full solution; this sounds like homework).
Simple recursive solution. Two sets are the first letter and the rest of the word. Find all combinations on the rest of the word. Then put the second letter with the first, and find all combinations on the rest of the word. Repeat until the rest of the word is 1 letter.
It's just a power set isn't it? For every position between two letters in your string you do or do not have a space. So for a string of length 6 there are 2 to the power of 5 possibilities.
A simple recursive function will enumerate all the possibilities. Do you need help writing such a function or were you just looking for the algorithm?
Between each letter, there's either a separator or there isn't. So recursively go through the word, trying out all combinations of separators/no-separators.
function f( word )
set = word[0] + f( substring(word, 1) )
set += word[0] + " " + f( substring(word, 1) )
return set;
My solution
Make it something like
void func(string s)
{
int len=s.length();
if(len==0)
return;
for(int i=1;i<=len;i++)
{
for(int j=0;j<i;j++)
cout<<s[j];
cout<<" ";
func(s[i]);
}
return;
}
Recursion. In java:
public static List<List<String>> split (String str) {
List<List<String>> res = new ArrayList<List<String>>();
if (str == null) {
return res;
}
for (int i = 0; i < str.length() - 1; i++) {
for (List<String> list : split(str.substring(i + 1))) {
List<String> tmpList = new ArrayList<String>();
tmpList.add(str.substring(0, i + 1));
for (String s : list) {
tmpList.add(s);
}
res.add(tmpList);
}
}
List<String> tmpList = new ArrayList<String>();
tmpList.add(str);
res.add(tmpList);
return res;
}
public static void main(String[] args) {
for (List<String> intermed : split("HAVING")) {
for (String str : intermed) {
System.out.print(str);
System.out.print(" ");
}
System.out.println();
}
}