Click here to Skip to main content
15,887,485 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello, I am learning c# and I am just a beginner.
In this code, my function gets an array of strings as the parameter then inside the function I have a variable named
C#
result
which in every iteration a new string will be concatenated to it. The problem that I have is that if I set
C#
digits = {"21" , "2"}

then the output will be
C#
212
but it must be
C#
221
but I do not know how to change my
C#
if
statement to correct the code now the code works fine for an array like
C#
{"3" , "23"}


And here is my full code :
using System;
using System.Collections.Generic;
using System.Linq;

namespace codeproject
{

    class Program
    {


        /// <summary>
            // LargestNumber(Digits):
            // answer ← empty string
            // while Digits is not empty:
                // maxDigit ← −∞
                // for digit in Digits:
                    // if digit ≥ maxDigit:
                        // maxDigit ← digit
                // append maxDigit to answer
                // remove maxDigit from Digits
            // return answer
        /// </summary>
        static string LargestNumber(string[] digits)
        {
            List<string> mylist = digits.ToList();
            string result="";
            while(mylist.Count != 0)
            {
                string max = "       ";
                foreach(var d in mylist)
                {
                    if(d[0] - '0' > max[0] - '0')
                    {
                        max = d;
                    }
                }
                result+=max;
                mylist.Remove(max);
            }
            return result;
        }

        static void Main(string[] args)
        {
            
            string[] myarray = new string[]{"23" , "3"};
            System.Console.WriteLine(LargestNumber(myarray));
        }
    }
}


What I have tried:

First, this code did not give me a correct output when I set
C#
digits={"23", "3"}
so I compare the first digit of every
C#
string
in
C#
if
statement. I will be grateful for your help and advice.
Posted
Updated 30-Aug-21 15:37pm

Assuming you want the largest number one can obtain by reshuffling the elements of the array (without breaking them up to individual digits), the job isn't straightforward.

Try an array holding 6 and 65; it should yield 665.
Now consider 6 and 67; it should yield 676.
The different precedence is caused by the second digit in 67 being larger than the first one, which isn't the case in 65.

The correct solution requires a special comparer that basically tries both orderings of two strings, like so:
C#
		public int ConcatComparer(string s1, string s2) {
			//long diff = long.Parse(s2+s1)-long.Parse(s1+s2);
			//if (diff>0) return 1;
			//if (diff<0) return -1;
			//return 0;

			// no need for numeric values, textual string.compare is
			// equivalent when strings have equal length; it is faster
			// and isn't limited to the int/long range

			return string.Compare(s2+s1, s1+s2);

}


and it gets used like this:
C#
				Array.Sort(myarray, ConcatComparer);
				s=string.Join("", myarray);
}


This yields the correct result even for
C#
string[] myarray = new string[] { "23", "1", "101", "3", "6", "67", "65" };


:)
 
Share this answer
 
v13
Comments
Maciej Los 31-Aug-21 7:57am    
5ed!
Aylin Naebzadeh 31-Aug-21 11:13am    
Thank you, Luc Pattyn. Yes, when I have tried the solution of Wendelius it was a bit slow I think that was because of the recursive strategy. Now if I give an array to the input of this function I should compare the elements two by two using a for loop block am I right?
Luc Pattyn 31-Aug-21 11:30am    
The built-in Array.Sort() method sorts the array, which means it rearranges the content of the array according to the result of the comparer given to it; everything you need has been shown, it is just one method plus two lines of code!
Aylin Naebzadeh 31-Aug-21 11:41am    
Yes, thank you again.
Why do you do this with strings? It would be easier if all the elements would be numbers. Consider the following example

C#
double[] digits = new double[]{ 3, 23 };
double newNumber;

newNumber = digits.Max() + (digits.Min() * System.Math.Pow(10, digits.Max().ToString().Length));


Note that I've used Linq to fetch the max and min values from the array. For more information, see Enumerable.Max Method (System.Linq) | Microsoft Docs[^]

--------------------------------------------
Added based on the updated requirement
--------------------------------------------

This could of course be a standard method but with an extension it could look something like
C#
/// <summary>
/// Class for extensions
/// </summary>
public static class Extensions {
   /// <summary>
   /// Finds the greatest number that can be found by concatenating the string in different orders
   /// </summary>
   /// <param name="values">List of strings</param>
   /// <returns>The concatenation that results to the greatest number</returns>
   public static string MaxCombination(this List<string> values) {
      double max = 0;
      List<string> newList;
      string combination;

      if (values.Count() == 1) {
         return values[0];
      }
      foreach (string value in values) {
         newList = new List<string>();
         newList.AddRange(values);
         newList.Remove(value);
         combination = newList.MaxCombination();
         combination = value + combination;
         if (double.Parse(combination) > max) {
            max = double.Parse(combination);
         }
      }

      return max.ToString();
   }
}

So calling it could look like
C#
List<string> theList = new List<string> { "3", "23", "101", "1" };
string max = theList.MaxCombination();
Trace.WriteLine(max);

And the output would be
3231101
 
Share this answer
 
v3
Comments
Aylin Naebzadeh 30-Aug-21 3:36am    
Yes, you are right it is obviously better to work with numbers instead of strings😅 , but when I set the digits array = new double[]{ 3, 23, 101, 1 } it prints 1101 in the output🤔
Wendelius 30-Aug-21 9:53am    
Yes, it took the greatest number (101) and added the least number (1) before it. Wasn't this the requirement?
Aylin Naebzadeh 30-Aug-21 11:28am    
Hmmmmm🤔🤔🤔no it was not. Something that I want is to find the largest number which can be created by concatenating the elements in the array.
Wendelius 30-Aug-21 13:55pm    
Okay this was a bit different from what I understood. Have a look at the updated solution
Aylin Naebzadeh 30-Aug-21 14:13pm    
Thank you, @Wendelius. I am really grateful for your help. Sorry if my question was not clear. So your strategy was to use recursive functions, am I right? because I think you have called your function inside the foreach block.
The simplest solution is to sort them - there are Linq methods to do that, and combined with the string.Join method it's one line of code:
C#
string[] myarray = new string[] { "23", "1", "101", "3" };
string s = string.Join("", myarray.OrderBy(a => int.Parse(a)));
 
Share this answer
 
Comments
CPallini 30-Aug-21 2:08am    
5.
Maciej Los 30-Aug-21 3:19am    
5ed!
Aylin Naebzadeh 30-Aug-21 3:30am    
I have tried your code but after sorting this array and when I run the code the output is: 1323101, but the largest that can be made is 3231101🤔am I right?
BillWoodruff 30-Aug-21 16:44pm    
the largest is 3321110: see my post below.
Aylin Naebzadeh 30-Aug-21 3:38am    
Maybe I did not ask my question in the post clearly. But something that I want from my code is to return the largest number that can be made by concatenating the elements in the array.
A word of caution: the technique I'll show you here is how I would do this, but, if this is homework, and the assignment requires you use a while loop, and, you turn this in: it's going to be obvious you didn't write this, and, I'd guess you would not be able to explain how this works.
// required: using System.Linq;

string[] myarray = new string[] { "23", "1", "101", "3" };
string s = string.Join("", myarray);

UTF8Encoding utf8 = new UTF8Encoding();

byte[] ba = utf8.GetBytes(s).OrderByDescending(b => b).ToArray();

string s2 = utf8.GetString(ba); // => 3321110
 
Share this answer
 
Comments
Luc Pattyn 31-Aug-21 7:57am    
hmm.
you might simplify that using String.ToCharArray()...

:)
Maciej Los 31-Aug-21 7:57am    
5ed!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900