So here is my code:
Console.Write("Insert first array length: ");
string[] izmers1 = new string[Convert.ToInt32(Console.ReadLine())];
Console.Write("Insert second array length: ");
string[] izmers2 = new string[Convert.ToInt32(Console.ReadLine())];
for (int i = 0; i < izmers1.Length; i++)
{
Console.Write("Insert 1.array {0} array value: ", i + 1);
izmers1[i] = Console.ReadLine();
}
for (int j = 0; j < izmers2.Length; j++)
{
Console.Write("Insert 2.array {0} array value: ", j + 1);
izmers2[j] = Console.ReadLine();
}
for (int k = 0; k < izmers1.Length; k++)
{
Console.WriteLine("1.array {0} value is {1}", k + 1, izmers1[k]);
}
for (int p = 0; p < izmers2.Length; p++)
{
Console.WriteLine("2.array {0} value is {1}", p + 1, izmers2[p]);
}
I need to create a loop or something , that will create combination of array's.
Imagine we entered length 3 and 4.
Then insert some value for each, our output is:
1.array 1.value q
1.array 2.value w
1.array 3.value e
2.array 1.value Q
2.array 2.value W
2.array 3.value E
2.array 4.value R
i need to create a combination that will look like this one qQwWeER.
My english is not very good, so i hope someone understand what i need and can explain how to get it :)
You can use Linq's Enumerable.Range, Enumerable.Aggregate along with a StringBuilder to create the combined string:
var s = Enumerable.Range(0, Math.Max(izmers1.Length, izmers2.Length)).Aggregate(new StringBuilder(), (sb, i) =>
{
if (i < izmers1.Length) sb.Append(izmers1[i]);
if (i < izmers2.Length) sb.Append(izmers2[i]);
return sb;
}).ToString();
}
Update You need to learn to read Linq and lambda expressions, they are an integral part of the language and are used extensively. The code I wrote also could be rewritten as follows:
StringBuilder sb = new StringBuilder();
for (int i = 0, length = Math.Max(izmers1.Length, izmers2.Length); i < length; i++)
{
if (i < izmers1.Length) sb.Append(izmers1[i]);
if (i < izmers2.Length) sb.Append(izmers2[i]);
}
var s = sb.ToString();
This works too:
var result =
String.Join("", Enumerable.Zip(
izmers1.Concat(Enumerable.Repeat("", izmers2.Length)),
izmers2.Concat(Enumerable.Repeat("", izmers1.Length)),
(i1, i2) => i1 + i2));
It's worth learning some of these approaches as they can make your coding so much simpler.
Related
Can anyone help me to find most efficient way to print character occurrence along with that character in a given string in alphabetical order?
I am able to count occurrence of character in string but I am not able to sort it in alphabetical order.
string OutputString = string.Empty;
int count = 1;
char[] charArr = inputString.ToCharArray();
for (int i = 0; i < charArr.Length; i++) {
for (int j = i + 1; j < charArr.Length; j++) {
if (charArr[i] == charArr[j])
count++;
}
if (!OutputString.Contains(charArr[i]))
OutputString += charArr[i].ToString() + count.ToString();
count = 1;
}
OutputString = string.Concat(OutputString.OrderBy(c => c));
let's say input string in xgdgyd
output should be:
d2g2x1y1.
You can use Linq to simplify this:
string s = "xgdgyd";
var result = s
.GroupBy(c => c)
.Select(g => g.Key.ToString() + g.Count())
.OrderBy(x => x);
Console.WriteLine(string.Concat(result)); // Outputs "d2g2x1y1"
The most useful thing here is GroupBy(), which will group all identical items together. That allows us to use g.Count() to count the number of items in each group.
Then we just concatenate each group key (a char) with its count into a single string.
Example on .Net Fiddle.
(I've simplified the code to use string.Concat() rather than string.Join() here.)
Solution given by #Matthew with LINQ is perfect, but if you want a solution with for loops as you posted in question then do this.
sort inputString first, and remove the line of code that sorts OutputString at the end, like this::
string inputString = "xgdgyd";
inputString = string.Concat(inputString.OrderBy(c => c));
string OutputString = string.Empty;
int count = 1;
char[] charArr = inputString.ToCharArray();
for (int i = 0; i < charArr.Length; i++)
{
for (int j = i + 1; j < charArr.Length; j++)
{
if (charArr[i] == charArr[j])
count++;
}
if (!OutputString.Contains(charArr[i]))
OutputString += charArr[i].ToString() + count.ToString();
count = 1;
}
Since you might not yet know LINQ, here is a solution using "classic" techniques:
string input = "xgdgyd";
char[] charArr = input.ToCharArray();
Array.Sort(charArr); // Sort before counting as Gian Paolo suggests!
// ==> "ddggxy"
int count;
string output = "";
for (int i = 0; i < charArr.Length; i += count) { // Increment by count to get
// the next different char!
count = 1;
// Note that we can combine the conditions within the for-statement
for (int j = i + 1; j < charArr.Length && charArr[j] == charArr[i]; j++) {
count++;
}
output += charArr[i] + count.ToString();
}
Console.WriteLine(output); // ==> d2g2x1y1
Note that the increment i += count, which is equivalent to i = i + count is performed at the end of the for-loop. Therefore count will be initialized at this point.
Another variant that uses only one loop instead of two nested loops appends the previous character to the output and resets the counter as soon as a different character is found.
string input = "xgdgyd";
char[] charArr = input.ToCharArray();
Array.Sort(charArr); // Sort before counting as Gian Paolo suggests!
int count = 1;
string output = "";
for (int i = 1; i < charArr.Length; i++) {
if (charArr[i] == charArr[i - 1]) {
count++;
} else {
output += charArr[i - 1] + count.ToString();
count = 1;
}
}
// Output last char
output += charArr[charArr.Length - 1] + count.ToString();
Console.WriteLine(output);
A more advanced technique would be to use a StringBuilder. See Concatenating Strings Efficiently by Jon Skeet.
I have a text file that is being read in and then stored in a string[] which I then then convert into an int[], my bubblesort then should sort it but it doesn't because the values from the text files are decimals. So my question is how do I convert either the string[] or int[] to something that can accept decimal values, such as a double[] if there is such a thing. Thanks.
Code:
string[] sh1OpenData = File.ReadAllLines("SH1_Open.txt");
...
else if(input2.ToLower() == "open") //----
{
int[] intSh1OpenData = new int[sh1OpenData.Length];
for (int x = 0; x < sh1OpenData.Length; x++)
{
intSh1OpenData[x] = Convert.ToInt32(sh1OpenData[x]);
}
Console.WriteLine("\n");
Console.WriteLine("Unsorted");
for (int i = 0; i < intSh1OpenData.Length; i++)
{
Console.Write(intSh1OpenData[i] + " ");
Console.WriteLine(" ");
}
int temp = 0;
for (int write = 0; write < intSh1OpenData.Length; write++)
{
for (int sort = 0; sort < intSh1OpenData.Length - 1; sort++)
{
if (intSh1OpenData[sort] > intSh1OpenData[sort + 1])
{
temp = intSh1OpenData[sort + 1];
intSh1OpenData[sort + 1] = intSh1OpenData[sort];
intSh1OpenData[sort] = temp;
}
}
}
Console.WriteLine("\n\n\nSORTED");
for (int i = 0; i < intSh1OpenData.Length; i++)
Console.Write(intSh1OpenData[i] + "\n");
}
You should not be using int to do comparisons on string. Use String.Compare(return 0 if equal, -1 if less than, or 1 if greater than) or List.Sort() to sort string array
Pretty simple with LINQ
var asDouble = sh1OpenData.Select(x => Double.Parse(x)).OrderBy(x => x).ToArray();
This will give you a sorted (ascending order) array of Double.
Note: this assumes that all of sh1OpenData can be parsed as a Double, and will throw an exception if not.
The only changes that you will need to make are listed below:
double[] intSh1OpenData = new double[sh1OpenData.Length]; // double[] instead of int[]
for (int x = 0; x < sh1OpenData.Length; x++)
{
intSh1OpenData[x] = Convert.ToDouble(sh1OpenData[x]); // Convert to Double
}
also change the declaration of your temp variable to double temp;
Something that you could read through since you mentioned that you are new to programming:
C# Sort Arrays and Lists Examples
MSDN: List.Sort Method
I am trying to create a column to count how much a number is generated. Here is an example of the output I would like:
Number 1 has been generated 5 times.
Number 2 has been generated 2 times.
etc.
Here is my current code:
Random r = new Random();
int plus = 0;
for (int a = 0; a < 10; a++)
{
plus++;
Console.Write("Week {0}: ", plus );
for (int i = 0; i < 7; i++)
{
Console.Write(r.Next(1, 11));
Console.Write(", ");
}
Console.WriteLine();
}
Use a Dictionary<int,int>, where the key is the random number and the value is the count:
var count = new Dictionary<int, int>();
for (int i = 0; i < 7; i++)
{
var rndValue = r.Next(1, 11);
if (count.ContainsKey(rndValue))
count[rndValue]++;
else
count.Add(rndValue, 1);
Console.Write(rndValue);
Console.Write(", ");
}
foreach (var c in count)
Console.WriteLine("Number {0} has been generated {1} time(s).", c.Key, c.Value);
If you want to print the results for any numbers that are generated 0 times, you'll have to add some additional code to make sure a value of 0 is stored in the Dictionary for those values.
Something like this before the foreach statement should work for you:
for (var i = 1; i < 11; i++)
if (!count.ContainsKey(i))
count.Add(i, 0);
An alternate solution, using a single-dimensional array, as suggested in the comments. A Dictionary is pretty straight-forward, but this may be even easier to understand.
var count = new int[10];
for (int i = 0; i < 7; i++)
{
var nextRnd = r.Next(1, 11);
count[nextRnd - 1]++;
Console.Write(nextRnd);
Console.Write(", ");
}
for (var i = 0; i < count.Length; i++)
Console.WriteLine("Number {0} has been generated {1} time(s).", i + 1, count[i]);
I'd like to using a Dictionary to implement this function:
Dictionary<int,int> rand_count_list = new Dictionary<int,int>();
Random r = new Random();
int plus = 0;
for (int a = 0; a < 10; a++)
{
plus++;
Console.Write("Week {0}: ", plus);
for (int i = 0; i < 7; i++)
{
int rand = r.Next(1, 11);
if (rand_count_list.ContainsKey(rand))
rand_count_list[rand]++;
else
rand_count_list[rand] = 1;
Console.Write(rand);
Console.Write(", ");
}
Console.WriteLine();
}
foreach (int key in rand_count_list.Keys)
{
Console.Write("Number {0} has been generated {1} times. ", key, rand_count_list[key]);
}
var r = new Random();
var weeks = new List<List<int>>(
Enumerable.Range(0, 10)
.Select(w => new List<int>(Enumerable.Range(0, 7)
.Select(i => r.Next(1, 11)))));
foreach (var week in weeks)
{
Console.WriteLine("Week {0}: {1}", weeks.IndexOf(week), string.Join(",", week));
}
var allNumbers = weeks.SelectMany(n => n);
foreach (var number in allNumbers.Distinct().OrderBy(n => n))
{
Console.WriteLine("{0} was generated {1} times",
number,
allNumbers.Count(n => n == number));
}
I have created a multi-dimensional array:
string[,] array_questions = new string[dt.Rows.Count, dt.Columns.Count];
for (i = 0; i < dt.Rows.Count; i++)
{
for (j = 0; j < dt.Columns.Count; j++)
{
array_questions[i, j] = dt.Rows[i][j].ToString();
//Response.Write(array_questions[i, j]);
}
// Response.Write(Environment.NewLine);
//Response.Write("\n");
}
foreach (string number in array_questions)
{
//Response.Write(number + " ");
//Response.Write(Environment.NewLine);
Response.Write(string.Join(", ", number) + Environment.NewLine);
}
but it shows an error like : Error 1 The best overloaded method match for 'string.Join(string, string[])' has some invalid arguments.. Please help
You do not need a for loop to join the string.
string.Join(", ", array_questions)
Replace the code
foreach (string number in array_questions)
{
//Response.Write(number + " ");
//Response.Write(Environment.NewLine);
Response.Write(string.Join(", ", number) + Environment.NewLine);
}
with
Response.Write(string.Join(", ", array_questions) + Environment.NewLine);
You need to flatten your array to use string.Join. It takes the separator and a single dimensional array, so you may proabably need to do something like this. But not sure what you are trying to achieve here. You are trying to call string.Join(string, string[]) as string.Join(string, string)
Try something like this:
var sdArray= new List<string>();
for (var i = 0; i < dt.Rows.Count; i++) //Get the length of first Dimension
{
for (var j = 0; j < dt.Columns.Count; j++) //Get the length of second Dimension
{
sdArray.Add(array_questions[i, j]);
}
}
///
Response.Write(string.Join(", ", sdArray) + Environment.NewLine);
Using Linq you can flatten this in a better way.
Something like this
string joinedSetOfQns= string.Join(",",
Enumerable.Range(0, dt.Rows.Count)
.SelectMany(i => Enumerable.Range(0, dt.Columns.Count)
.Select(j => array_questions[i, j])));
Response.Write(joinedSetOfQns + Environment.NewLine);
This is the defenision for string.Join
public static string Join(
string separator,
params string[] value /// <-- Takes single Dimensional Array not a string.
)
Update: Since you need to join Rowwise
for (var i = 0; i < dt.Rows.Count; i++)
{
var result = new List<string>();
for (var j = 0; j < dt.Columns.Count; j++)
{
result.Add(array_questions[i, j]);
}
Response.Write(string.Join(", ", result) + Environment.NewLine);
}
Let's say you have the string "This is a test"
I pass it to method zee, like ("This is a test", 1)
and want "test This is a";
I pass it to method zee, like ("This is a test", 2)
and want "a test This is";
the number can exceed the total words in variable. If it does it should loop around.
I started with....
public static string zee(string origString, int i)
{
StringBuilder sb = new StringBuilder();
ArrayList list = new ArrayList();
list.AddRange(origString.Split(' '));
// not sure here -
for (int c = i; c < (list.Count + i); c++)
{
sb.AppendFormat("{0} ", list[c]);
}
return sb.ToString();
}
for(int j=0; j < list.length; j++){
int idx = (j + i) % list.length;
sb.AppendFormat("{0} " , list[idx]);
}
Mostly like Brent Arias's solution, but I think a for loop is more readable, less likely to go infinite.
public static string zee(string origString, int i)
{
StringBuilder sb = new StringBuilder();
List<string> list = new List<string>();
list.AddRange(origString.Split(' '));
for (int j = 0; j < list.Count; j++)
{
int idx = (j + i) % list.Count;
sb.AppendFormat("{0} ", list[idx]);
}
return sb.ToString();
}
This is how I'd solve it.
private static string f(string s, int start)
{
var arr=s.Split(' ');
start %= arr.Length;
var res=arr.Skip(arr.Length - start).ToList();
res.AddRange(arr.Take(arr.Length - start));
return string.Join(" ", res);
}
I tried writing a one liner with linq but I don't see how to combine 2 lists. Union and Join aren't what I need.
This is how I'd solve it using strings.
public static string zee(string origString, int i)
{
string[] splitStr = origString.Split(' ');
string newStr = "";
// Not sure what you meant by wrap around but this should
// do the trick.
i %= splitStr.Length;
for (int j = (splitStr.Length - i); j < splitStr.Length; j++)
newStr += splitStr[j] + " "; // Add spaces taken by split :(
for (int j = 0; j < (splitStr.Length - i); j++)
newStr += splitStr[j] + " ";
return
newStr;
}
Here's an abomination trying to cram as much into one line as possible:
static string zee(string sentence, int wordCount)
{
var words = sentence.Split(' ');
return string.Join(" ", new[] { words.Skip(words.Count() - wordCount), words.Take(words.Count() - wordCount) }.SelectMany(w => w).ToArray());
}
I havn't tried it, but I think this would do it:
i %= list.Length;
int index = i;
do {
index %= list.Length;
sb.AppendFormat("{0} ", list[index]);
while (++index != i);
static string rearrange(string phase,int index)
{
string[] words = phase.Split(' ');
string[] newwords = new string[words.Length];
int pointer = index;
for (int i = 0; i < words.Length;i++ )
{
if(pointer>=words.Length)
{
pointer = 0;
}
newwords[i] = words[pointer];
pointer++;
}
return string.Join(" ", newwords);
}
Sounds like a homework question to me, but here is an efficient use of the .Net framework:
private static string [] SplitWords(string s, int startWord)
{
string[] words = s.Split(' ');
List<string> output = new List<string>();
output.AddRange(words.Skip(startWord).ToArray());
output.AddRange(words.Take(startWord).ToArray());
return output.ToArray();
}
There is absolutely no error checking in this function so you will have to modify it for production code but you get the idea.
public string SetStart(int startAt)
{
const string sentence = "this is a test so it is";
var words = sentence.Split(' ');
var x = (startAt > words.Count()) ? startAt%words.Count() : startAt;
return string.Join(" ", words.Skip(x).Concat(words.Take(x)));
}