Strings sorteren op ingesloten nummers in Java

1. Inleiding

In deze zelfstudie bekijken we hoe u alfanumeriek kunt sorteren Draads door de nummers die ze bevatten. We zullen ons concentreren op het verwijderen van alle niet-numerieke tekens uit de Draad voordat u meerdere sorteert Snaren door de numerieke tekens die overblijven.

We kijken naar veelvoorkomende randgevallen, inclusief lege Draads en ongeldige nummers.

Ten slotte zullen we onze oplossing testen om er zeker van te zijn dat deze werkt zoals verwacht.

2. Het probleem schetsen

Voordat we beginnen, moeten we beschrijven wat we met onze code willen bereiken. Voor dit specifieke probleem maken we de volgende aannames:

  1. Onze strings mogen alleen cijfers bevatten, alleen letters of een combinatie van beide.
  2. De getallen in onze strings kunnen gehele getallen of dubbele getallen zijn.
  3. Als cijfers in een string worden gescheiden door letters, moeten we de letter verwijderen en de cijfers samen condenseren. Bijvoorbeeld, 2d3 wordt 23.
  4. Eenvoudigheidshalve moeten we, wanneer een ongeldig of ontbrekend nummer verschijnt, deze als 0 behandelen.

Nu dit is vastgesteld, gaan we ons verdiepen in onze oplossing.

3. Een Regex-oplossing

Omdat onze eerste stap is om te zoeken naar numerieke patronen binnen onze invoer Draad, we kunnen reguliere expressies gebruiken, algemeen bekend als een regex.

Het eerste dat we nodig hebben, is onze regex. We willen alle gehele getallen behouden, evenals decimale punten van de invoer Draad. We kunnen ons doel bereiken met het volgende:

String DIGIT_AND_DECIMAL_REGEX = "[^ \ d.]" String digitsOnly = input.replaceAll (DIGIT_AND_DECIMAL_REGEX, "");

Laten we kort uitleggen wat er gebeurt:

  1. ‘[^ ]' - duidt een genegeerde set aan en richt zich daarom op elk teken dat niet is gespecificeerd door de ingesloten regex
  2. ‘\ D ' - match een willekeurig cijfer (0 - 9)
  3. ‘.' - overeenkomen met een "." karakter

We gebruiken dan String.replaceAll methode om alle tekens te verwijderen die niet zijn gespecificeerd door onze regex. Hierdoor kunnen we ervoor zorgen dat de eerste drie punten van ons doel behaald kunnen worden.

Vervolgens moeten we enkele voorwaarden toevoegen om ervoor te zorgen dat deze leeg en ongeldig zijn Snaren retourneer 0, hoewel geldig Snaren retourneer een geldig Dubbele:

if ("". equals (digitsOnly)) retourneert 0; probeer {return Double.parseDouble (digitsOnly); } catch (NumberFormatException nfe) {return 0; }

Dat maakt onze logica compleet. Het enige dat u hoeft te doen, is het op een comparator aansluiten, zodat we het gemakkelijk kunnen sorteren Lijsten van input Snaren.

Laten we een efficiënte methode bedenken om onze comparator te retourneren, waar we maar willen:

openbare statische Comparator createNaturalOrderRegexComparator () {retourneer Comparator.comparingDouble (NaturalOrderComparators :: parseStringToNumber); }

4. Test, test, test

Wat heb je aan code zonder tests om de functionaliteit ervan te verifiëren? Laten we een snelle unit-test opzetten om er zeker van te zijn dat alles werkt zoals we gepland hadden:

Lijst testStrings = Arrays.asList ("a1", "d2.2", "b3", "d2.3.3d", "c4", "d2.f4",); // 1, 2.2, 3, 0, 4, 2.4 testStrings.sort (NaturalOrderComparators.createNaturalOrderRegexComparator ()); Lijst verwacht = Arrays.asList ("d2.3.3d", "a1", "d2.2", "d2.f4", "b3", "c4"); assertEquals (verwacht, testStrings);

In deze unit-test hebben we alle scenario's ingepakt die we hebben gepland. Ongeldige getallen, gehele getallen, decimalen en letters gescheiden getallen allemaal opgenomen in onze testStrings variabele.

5. Conclusie

In dit korte artikel hebben we laten zien hoe alfanumerieke strings kunnen worden gesorteerd op basis van de getallen erin - door gebruik te maken van reguliere expressies om het harde werk voor ons te doen.

We hebben standaard uitzonderingen afgehandeld die kunnen optreden bij het parseren van invoertekenreeksen en hebben de verschillende scenario's getest met eenheidstests.

Zoals altijd is de code te vinden op GitHub.