1
votes

Comment union des chaînes dans une liste en C #

J'ai une liste de chaînes qui fournissent des informations sur un voyage en jours par exemple "0111110" signifie que les voyages ne sont pas disponibles le premier et le dernier jour de la semaine.

Il existe maintenant une liste qui contient des informations comme "0111110", "1000001"

donc le jour de l'opération pour le bloc entier sera "1111111".

Ma question est de savoir comment fusionner efficacement des voyages pour obtenir des jours opérationnels bloqués?


1 commentaires

La réponse simple est d'utiliser une structure de données appropriée et non une chaîne.


5 Réponses :


5
votes

Vous pouvez utiliser le | Opérateur (OR bit à bit):

var x1 = Convert.ToByte("0111110", 2);
var x2 = Convert.ToByte("1000001", 2);

var foo = x1 | x2;

var bar = Convert.ToString(foo, 2);


0 commentaires

0
votes

Avec des boucles imbriquées:

byte r = 0;
for(int i = 0; i < strs.Length && r != 127; i++)
  r |= Convert.ToByte(strs[i], 2);

string res = Convert.ToString(t, 2).PadLeft(7, '0');

C'est plus verbeux que kristoffer au niveau du bit ou mais cela devrait être assez rapide si vous fusionnez un grand nombre de chaînes, car il abandonne dès qu'il fait un 1 dans une position particulière. L'approche ou au niveau du bit est un peu plus naïve et entraînerait plus de conversions inutiles. Lequel est le plus performant dépend probablement des particularités de votre situation. L'approche au niveau du bit peut également avoir des problèmes de remplissage / longueur et est limitée à 8 chiffres si vous utilisez byte; vous n'avez que 7 jours, mais quelqu'un pourrait le mettre à niveau pour faire des mois complets un jour. Cette approche n'a pas de limite à cet égard

Une approche bit à bit "N nombre de chaînes":

string[] strs = new string[] { "0111110", "1000001" };

char[] main = strs[0].ToCharArray();



for(int i = 0; i < 7; i++)
{
    if(main[i] == '1')
        continue;
    for(int j = 1; j < strs.Length; j++)
    {
        if(strs[j][i] == '1')
        {
            main[i] = '1';
            break;
        }
    }
}

string result = new string(main);

Nous pouvons nous arrêter tôt si nous frappons 127 car cela indique que vous avez atteint 1111111. Les zéros non significatifs sont perdus et doivent être restaurés avec PadLeft


0 commentaires

0
votes

En supposant que vous ne pouvez pas utiliser un type différent des chaînes que vous avez fournies, vous pouvez copier les résultats dans un tableau et créer une chaîne à partir de celui-ci:

var result = new char[7];
for (int i=0; i<7; i++)
    if (s1[i] == '1' || s2 == ['1'])
        result[i] = '1';

var finalResult = new string(result);

Ceci est efficace car vous ne ont deux allocations (le tableau et la chaîne), sept itérations / comparaisons et jusqu'à sept copies de caractères.


0 commentaires

0
votes
    public static class OperationalBlockCalculator
    {
        public static string GetOperationalBlock(List<string> workingDays)
        {
            var operationalBlock = new StringBuilder("0000000");
            for (var day = 0; day < 7; day++)
            {
                if (workingDays.Any(x => x.ElementAt(day).Equals('1')))
                {
                    operationalBlock[day] = '1';
                }
            }
            return operationalBlock.ToString();
        }
    }

    [TestFixture]
    public class WhenIMergeTripWorkingDays
    {
        [Test]
        public void ThenItShouldReturnOperationalBlock()
        {
            var workingDays = new List<string> { "0110110", "1000001" };
            OperationalBlockCalculator.GetOperationalBlock(workingDays).Should().Be("1110111");
        }
    }

0 commentaires