Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I'm trying to add Countries to an Excel Document with some information on adoption. The information is online at HERE. I've been working this backwards so I can at least have something to show in the next couple hours. I've added what I really want to do at the bottom of this question in case you are curious.
I have found the problem to be with the carriage returns and newlines. I'm working on fixing that then I'll upload the solution.
I'm passing a string with about 450 words in it. I have 2 '>>>' and 2 '<<' in it. My output is only showing me that it only found 1 '>>>'. Is there something I'm missing? I'm about to start pulling my hair out.
private void FindCountries(string text) {
text = text.Replace("\n", " "); //This 3 lines fixed the problem.
text = text.Replace("\r", " "); //Without these and string in the array was
text = text.Replace("\t", " "); //looking like this: "<<\r\n\r>>>"
string[] helper = text.Split(' ');
//List<string> myContries = new List<string>();
List<int> j = new List<int>();
List<int> k = new List<int>();
for (int i = 0; i < helper.Length; i++) {
if (helper[i] == ">>>") {
Console.WriteLine(helper[i]);
Console.WriteLine("added to j");
j.Add(i);
}
if (helper[i] == "<<") {
Console.WriteLine("added to k");
k.Add(i);
}
}
Console.WriteLine("J");
foreach (var item in j) {
Console.WriteLine(item);
}
Console.WriteLine("K");
foreach (var item in k) {
Console.WriteLine(item);
}
}
Project description:
Go to a website.
Grab all the information.(Right now I'm here working my way up.)
Put it in an Excel Doc nicely.
A quick test with an input string of "foo << bar >>> baz >>> qux << quxx >>>" worked as expected.
Without knowing what the input is, I can only guess, but 1 possibility is that one of the occurrences of >>> is not delimited by a space on both sides, meaning it won't appear by itself when you split the input.
private void FindCountries(string text)
{
var words = text.Split(' ');
//List<string> myContries = new List<string>();
var tripleRights = new List<int>();
var doubleLefts = new List<int>();
for (var index = 0; index < words.Length; index++)
{
if (String.Equals(words[index], ">>>", StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine(words[index]);
Console.WriteLine("found a triple right");
tripleRights.Add(index);
}
if (String.Equals(words[index], "<<", StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine(words[index]);
Console.WriteLine("found a double left");
doubleLefts.Add(index);
}
}
Console.WriteLine("triple rights:");
foreach (var item in tripleRights)
{
Console.WriteLine(item);
}
Console.WriteLine("double lefts");
foreach (var item in doubleLefts)
{
Console.WriteLine(item);
}
}
You could simply do something like:
string test = "23 <<< hello <<< to >> here <<<";
int found=0;
int seek_pos =0;
while (true) {
var current = test.IndexOf("<<<", seek_pos);
if (current == -1)
break;
else {
Console.WriteLine("found one at position {0}, starting at: {1} ", current, seek_pos);
found++;
seek_pos = current + 3 ; // 3 chars in <<<
}
}
Console.WriteLine("Total found: {0} ",found);
Giving as results:
found one at position 3, starting at: 0
found one at position 13, starting at: 6
found one at position 28, starting at: 16
Total found: 3
Related
This question already has answers here:
Reverse the ordering of words in a string
(48 answers)
Closed 1 year ago.
I want to reverse an array with console.ReadLine(), but I'm stuck.
Here is statement of problem.
Give an array of 10 natural numbers. Displays the numbers in the string in reverse order.
The numbers in the string are given on a single line and are separated by a space. The application will display the numbers on a single line, separated by a space between them.
Example:
For input data:
1 2 3 4 5 6 7 8 9 10
The console will display:
10 9 8 7 6 5 4 3 2 1
here is my code:
string number = Convert.ToString(Console.ReadLine());
List<string> originalList = new List<string>();
for (int i = 0; i < 1; i++)
{
originalList.Add(number);
}
foreach (string item in originalList)
{
Console.Write(item + " ");
}
originalList.Reverse();
foreach (string item in originalList)
{
Console.WriteLine(item + " ");
}
Console.WriteLine();
The numbers in the string are given on a single line and are separated by a space.
The following code is incorrect because Console.ReadLine does not stop reading when it encounters whitespace. It will consume the entire input as one entry in originalList.
string number = Convert.ToString(Console.ReadLine());
List<string> originalList = new List<string>();
for (int i = 0; i < 1; i++)
{
originalList.Add(number);
}
// originalList is now [ "1 2 3..." ];
Instead, you should look at String.Split.
string input = Console.ReadLine();
List<string> originalList = input.Split(' ').ToList();
// originalList is now [ "1", "2", "3", ... ];
You can now use List.Reverse and String.Join to get your output.
originalList.Reverse();
string output = string.Join(' ', originalList);
Console.WriteLine(output);
Need either string.Split (' ') or a for loop or a while loop
Using string.Split (' ')
string [] splitArray = number.Split (' ');
for (int i = 0; i < splitArray.Length; i++)
{
originalList.Add(splitArray [i]);
}
//rest of the code would be same
For loop
String readvalues="";
for (int i=0;i <number.Length;i++)
{
if (i==number Length-1)
{
readvalues += number [i];
}
if (number[i]==" " || i==number.Length-1)
{
originalList.Add (readvalues);
readvalues="";
}
else
{
readvalues += number [i];
}
}
//rest of the code would be same
While loop
int index=0;
String readvalues="";
while (index < number.Length)
{
if (index==number.Length-1)
{
readvalues += number [index];
}
if (number[index]==" " ||index==number.Length-1)
{
originalList.Add (readvalues);
readvalues="";
}
else
{
readvalues += number [index];
}
index++;
}
//rest of the code would be same
I think, I have a solution for you, what you exactly ask for. Please check the code and let me know =>
void Test()
{
string number = Convert.ToString(Console.ReadLine());
List<string> originalList = new List<string>();
if(!string.IsNullOrEmpty(number) && !string.IsNullOrWhiteSpace(number) )
{
originalList=number.Split(" ").ToList();
originalList.Reverse();
Console.WriteLine(string.Join(" ", originalList));
}
}
Note : Use those three namespaces using System;,using System.Linq;,using System.Collections.Generic;
You can try querying the initial string with a help of Linq (Reverse):
Split string into items
Reverse these items
Join items back into string
Code:
using System.Linq;
...
// For Test (comment it out for release)
string source = "1 2 3 4 5 6 7 8 9 10";
// Uncomment for release
// string source = Console.ReadLine();
string result = string.Join(" ", source
.Split(' ', StringSplitOptions.RemoveEmptyEntries)
.Reverse());
Console.WriteLine(result);
Outcome:
10 9 8 7 6 5 4 3 2 1
I am here to ask how to read one string line, check if it is contained in a Dictionary and if so, add a number to it. For example if the input is Gold and the next line is 115: the number should be assigned to the string. Each time the loop rotates it should check if the string is contained and add the next int line to it.
var text = new SortedDictionary<string, int>();
while (true)
{
for (int i = 0; i < 2000000000; i++)
{
string[] sequenceOfStrings = Console.ReadLine()
.Split();
var material = sequenceOfStrings[0];
if (material == "stop")
{
break;
}
if (!text.ContainsKey(material))
{
text.Add(material, i);
}
You are given a sequence of strings, each on a new line. Every odd line on the console is representing a resource (e.g. Gold, Silver, Copper, and so on), and every even – quantity. Your task is to collect the resources and print them each on a new line. Print the resources and their quantities in format:
{resource} –> {quantity}. The quantities inputs will be in the range [1 … 2 000 000 000]
Thank you for the patience.
Tom
The code that solves your issue could look like this:
var text = new SortedDictionary<string, int>();
while (true)
{
string material = Console.ReadLine();
if(material == "stop")
{
break;
}
string quantityString = Console.ReadLine();
if (!Int32.TryParse(quantityString, out int newQuantity))
{
continue;
}
if (text.TryGetValue(material, out int currentQuantity))
{
text[material] = currentQuantity + newQuantity;
}
else
{
text[material] = newQuantity;
}
}
foreach(var item in text)
{
Console.WriteLine($"{item.Key} : {item.Value};");
}
BTW, do you really need SortedDictionary here? If you have a lot of keys then ( depending on input data distribution ) it could take a bit more time to do TryGetValue than for ordinary Dictionary.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I've been trying to figure out the best approach to combining words in a string to make combinations of that string. I'm trying to do this for a class project. If the string is "The quick fox", I need to find a way to output "Thequick fox", "the quickfox", and "thequickfox". I've tried using string.split and gluing them back together, but haven't had a lot of luck. The issues is the string input could be of any size.
I decided to try this for fun. The idea here is to split the bigger problems into smaller subproblems. So I first started with strings that had 0 and 1 space. I see that with 0 space, the only possible combinations is the string items. With 1 space, I can either have that space or not.
Then I just have to recursively divide the problem until I get one of the base cases. So to that do that I Skip elements in the split array in increments of 2. That way I am guaranteed to get one of the base cases eventually. Once I do that, I run it through the program again and figure out how to add all the results of that to my current set of combinations.
Here's the code:
class Program
{
static void Main(string[] args)
{
string test1 = "fox";
string test2 = "The quick";
string test3 = "The quick fox";
string test4 = "The quick fox says";
string test5 = "The quick fox says hello";
var splittest1 = test1.Split(' ');
var splittest2 = test2.Split(' ');
var splittest3 = test3.Split(' ');
var splittest4 = test4.Split(' ');
var splittest5 = test5.Split(' ');
var ans1 = getcombinations(splittest1);
var ans2 = getcombinations(splittest2);
var ans3 = getcombinations(splittest3);
var ans4 = getcombinations(splittest4);
var ans5 = getcombinations(splittest5);
}
static List<string> getcombinations(string[] splittest)
{
var combos = new List<string>();
var numspaces = splittest.Count() - 1;
if (numspaces == 1)
{
var addcombos = AddTwoStrings(splittest[0], splittest[1]);
var withSpacesCurrent = addcombos.Item1;
var noSpacesCurrent = addcombos.Item2;
combos.Add(withSpacesCurrent);
combos.Add(noSpacesCurrent);
}
else if (numspaces == 0)
{
combos.Add(splittest[0]);
}
else
{
var addcombos = AddTwoStrings(splittest[0], splittest[1]);
var withSpacesCurrent = addcombos.Item1;
var noSpacesCurrent = addcombos.Item2;
var futureCombos = getcombinations(splittest.Skip(2).ToArray());
foreach (var futureCombo in futureCombos)
{
var addFutureCombos = AddTwoStrings(withSpacesCurrent, futureCombo);
var addFutureCombosNoSpaces = AddTwoStrings(noSpacesCurrent, futureCombo);
var combo1 = addFutureCombos.Item1;
var combo2 = addFutureCombos.Item2;
var combo3 = addFutureCombosNoSpaces.Item1;
var combo4 = addFutureCombosNoSpaces.Item2;
combos.Add(combo1);
combos.Add(combo2);
combos.Add(combo3);
combos.Add(combo4);
}
}
return combos;
}
static Tuple<string, string> AddTwoStrings(string a, string b)
{
return Tuple.Create(a + " " + b, a + b);
}
}
}
This is how I got it working, not sure if it is the best algorithm.
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Enter a string");
string input = Console.ReadLine();
//split the input string into an array
string[] arrInput = input.Split(' ');
Console.WriteLine("The combinations are...");
//output the original string
Console.WriteLine(input);
//this loop decide letter combination
for (int i = 2; i <= arrInput.Length; i++)
{
//this loop decide how many outputs we would get for a letter combination
//for ex. we would get 2 outputs in a 3 word string if we combine 2 words
for (int j = i-1; j < arrInput.Length; j++)
{
int end = j; // end index
int start = (end - i) + 1; //start index
string output = Combine(arrInput, start, end);
Console.WriteLine(output);
}
}
Console.ReadKey();
}
//combine array into a string with space except from start to end
public static string Combine(string[] arrInput, int start, int end) {
StringBuilder builder = new StringBuilder();
bool combine = false;
for (int i = 0; i < arrInput.Length; i++) {
//first word in the array... don't worry
if (i == 0) {
builder.Append(arrInput[i]);
continue;
}
//don't append " " if combine is true
combine = (i > start && i <= end) ? true : false;
if (!combine)
{
builder.Append(" ");
}
builder.Append(arrInput[i]);
}
return builder.ToString();
}
}
I get a string from the user and then put it in a char array. Now I want to display all the characters in the string along with how many times they appear. My code is as follows Please Correct me ?
using System;
class count
{
public void charcount()
{
int i ;
int count = 0;
string s;
Console.WriteLine("Enter the String:");
s = Console.ReadLine();
char[] carr = s.ToCharArray();
for(i = 0; i < carr.Length; i++)
{
for(int j = 1; j < carr.Length; j++)
{
if(carr[j] == carr[i])
{
count++;
}
else
{
return;
}
Console.WriteLine("The Character " + carr[i] + " appears " + count);
}
}
}
static void Main()
{
count obj = new count();
obj.charcount();
}
}
Well, your code will at least have problems due to the fact that you don't build a list of unique characters, you find them in the original string. Any string with characters that appear multiple times will show odd results.
Here's a LINQ expression that calculates the information for you (you can run this in LINQPad to immediately see the results):
void Main()
{
string s = "This is a test, with multiple characters";
var statistics =
from c in s
group c by c into g
select new { g.Key, count = g.Count() };
var mostFrequestFirst =
from entry in statistics
orderby entry.count descending
select entry;
foreach (var entry in mostFrequestFirst)
{
Debug.WriteLine("{0}: {1}", entry.Key, entry.count);
}
}
Output:
: 6 <-- space
t: 5
i: 4
s: 4
h: 3
a: 3
e: 3
l: 2
c: 2
r: 2
T: 1
,: 1
w: 1
m: 1
u: 1
p: 1
If you can't use LINQ, here's an example that doesn't use that:
void Main()
{
string s = "This is a test, with multiple characters";
var occurances = new Dictionary<char, int>();
foreach (char c in s)
{
if (occurances.ContainsKey(c))
occurances[c] = occurances[c] + 1;
else
occurances[c] = 1;
}
foreach (var entry in occurances)
{
Debug.WriteLine("{0}: {1}", entry.Key, entry.Value);
}
}
It looks like you want an outer loop and an inner loop, and for each char in the array, you want to compare to each that follows with int j = 1. In that case, you want int j = i + 1 in the inner loop:
for (int i = 0; i < carr.Length; i++)
{
for (int j = i + 1; j < carr.Length; j++)
{
}
}
But your return statement exits the function right in the middle of things. You need to let the loops complete, so you want to remove that return.
Your Console.WriteLine executes on every iteration of the inner loop, but you really only want it to iterate on the outer loop -- once for each character of the string and not once for every combination of i and j. So you need to push that to the outer loop, outside of the inner loop.
Also, you need to reset the count every time you begin another iteration of the outer loop, because you are counting again, and, you want to start counting at 1 not zero when you find a character because it just appeared once as you first reach it.
And as Lasse points out, you'll get strange output when you hit the same character as you move along the outer loop. An easy way to prevent that is to set the further (rightwards) char[j] to '\0' (null character) on every match, and then in the outer loop, ignore null characters in your counting for example by using continue, effectively culling them as you go along:
for(int i = 0; i < carr.Length; i++)
{
if (carr[i] == '\0')
{
continue; // skip any further chars we've already set to null char
}
int count = 1;
for (int j = i + 1; j < carr.Length; j++)
{
if(carr[j] == carr[i])
{
carr[j] = '\0'; // don't look for this char again later
count++;
}
}
Console.WriteLine("The Character " + carr[i] + " appears " + count);
}
My first thought would be to use a Dictionary as Daniel suggests, like this:
var dict = new Dictionary<char, int>();
string s = "This is a test, with multiple characters";
foreach (var c in s)
{
if (dict.ContainsKey(c))
{
dict[c]++;
}
else
{
dict[c] = 1;
}
}
foreach (var k in dict.Keys)
{
Console.WriteLine("{0}: {1}", k, dict[k]);
}
But I like the elegant LINQ solutions.
If you would have tested your code, you would have realized, that the code is very wrong.
Some of its problems:
You have only one count variable, although you want to count the occurences of all characters in your string
You are comparing the string with itself and return from your method, as soon, as the characters don't match.
The right way would be to use a Dictionary<char, int> to hold the count for each character, something like this:
var counts = new Dictionary<char, int>();
foreach(var c in s)
{
int count;
if(!counts.TryGetValue(c, out count))
{
counts.Add(c, 1);
}
else
{
++counts[c];
}
}
I didn't use LINQ on purpose, because I don't think you would understand that code. That's no offence.
If you want to go the LINQ way, this is a fairly brief way to do it (which I realize is pretty much the same as Lasse V. Karlsen's answer, only using different syntax):
var s = Console.ReadLine();
foreach (var group in s.GroupBy(c => c).OrderByDescending(g => g.Count()))
{
Console.WriteLine(" {0}: {1}", group.Key, group.Count());
}
The logic is the same whatever approach you use:
Identify each unique character
Count how many times each character occurs in the text
Output the result
In my code sample, s.GroupBy(c => c) takes care of the first two steps. The call OrderByDescending(g => g.Count()) will just sort the result so that more frequent characters come first. Each element in the result has a Key property (the character) and (amongst others) a Count() method that will return the number of occurrences for that character.
I have a dictionary object IDictionary<string, string> which only has the following items:
Item1, Items2 and Item3. Each item only has a maximum length of 50 characters.
I then have a list of words List<string>. I need a loop that will go through the words and add them to the dictionary starting at Item1, but before adding it to the dictionary the length needs to be checked. If the new item and the current item's length added together is greater than 50 characters then the word needs to move down to the next line (in this case Item2).
What is the best way to do this?
I'm not sure why this question got voted down so much, but perhaps the reason is you have a very clear algorithm already, so it should be trivial to get the C# code. As it stands, either you're either really inexperienced or really lazy. I'm going to assume the former.
Anyways, lets walk through the requirements.
1) "I then have a list of words List." you have this line in some form already.
List<string> words = GetListOfWords();
2) "go through the words and add them to the dictionary starting at Item1" -- I'd recommend a List instead of a dictionary, if you're going for a sequence of strings. Also, you'll need a temporary variable to store the contents of the current line, because you're really after adding a full line at a time.
var lines = new List<string>();
string currentLine = "";
3) "I need a loop that will go through the words"
foreach(var word in words) {
4) " If the new item and the current item's length added together is greater than 50 characters" -- +1 for the space.
if (currentLine.Length + word.Length + 1 > 50) {
5) "then the word needs to move down to the next line "
lines.Add(currentLine);
currentLine = word;
}
6) " go through the words and add them to the dictionary starting at Item1 " -- you didn't phrase this very clearly. What you meant was you want to join each word to the last line unless it would make the line exceed 50 characters.
else {
currentLine += " " + word;
}
}
lines.Add(currentLine); // the last unfinished line
and there you go.
If you absolutely need it as an IDictionary with 3 lines, just do
var dict = new Dictionary<string,string>();
for(int lineNum = 0; lineNum < 3; lineNum ++)
dict["Address"+lineNum] = lineNume < lines.Length ? lines[lineNum] : "";
I currently have this and was wondering if there was perhaps a better solution:
public IDictionary AddWordsToDictionary(IList words)
{
IDictionary addressParts = new Dictionary();
addressParts.Add("Address1", string.Empty);
addressParts.Add("Address2", string.Empty);
addressParts.Add("Address3", string.Empty);
int currentIndex = 1;
foreach (string word in words)
{
if (!string.IsNullOrEmpty(word))
{
string key = string.Concat("Address", currentIndex);
int space = 0;
string spaceChar = string.Empty;
if (!string.IsNullOrEmpty(addressParts[key]))
{
space = 1;
spaceChar = " ";
}
if (word.Length + space + addressParts[key].Length > MaxAddressLineLength)
{
currentIndex++;
key = string.Concat("Address", currentIndex);
space = 0;
spaceChar = string.Empty;
if (currentIndex > addressParts.Count)
{
break; // To big for all 3 elements so discard
}
}
addressParts[key] = string.Concat(addressParts[key], spaceChar, word);
}
}
return addressParts;
}
I would just do the following and do what you like with the resulting "lines"
static List<string> BuildLines(List<string> words, int lineLen)
{
List<string> lines = new List<string>();
string line = string.Empty;
foreach (string word in words)
{
if (string.IsNullOrEmpty(word)) continue;
if (line.Length + word.Length + 1 <= lineLen)
{
line += " " + word;
}
else
{
lines.Add(line);
line = word;
}
}
lines.Add(line);
return lines;
}