Le code suivant est lui-même dans une boucle externe où oldChar est défini :

List<Character> modifiableCollection = new ArrayList<Character>(Arrays.asList(AlphabeticalStatistics.ALL_LETTERS));
for (int j = 0; j < modifiableCollection.size(); j++) {
    Character letterOfAlphabet = modifiableCollection.get(j);
    String loaAsString = letterOfAlphabet.toString();
    if (replaceLetters(Character.toString(oldChar), loaAsString)) {
        modifiableCollection.remove(j);
        System.out.println(oldChar + " was replaced with " + loaAsString);
        break;
    }
}

J'essaie de parcourir ALL_LETTERS le plus efficacement possible. Pour chaque élément, je veux vérifier si replaceLetters() sur cette lettre et une autre lettre. Si c'est le cas, la lettre sera remplacée et je souhaite la supprimer du modifiableCollection afin que la prochaine fois qu'elle soit bouclée, elle ne cherchera plus à remplacer cette lettre.

Cependant, ce que je vois, c'est utiliser une boucle for améliorée AVEC SUPPRESSION, le code s'exécute ET est plus efficace. Je ne dois pas supprimer dans une version améliorée pour :

 for (Character letterOfAlphabet : modifiableCollection) {...remove()} // Compiles 

, mais lorsque j'utilise une boucle for normale, comme ci-dessus, le programme prend plus de temps à s'exécuter ; lorsque j'utilise iterator, le programme prend encore plus de temps à s'exécuter. Dois-je m'en tenir à la boucle foreach ?

Modifier Méthode replaceLetters() :

protected boolean replaceLetters(String toReplace, String replacement, String toAdd, String toAdd2) {
        if (replacedLetters.contains(toAdd2) || solvedLetters.contains(toAdd)) 
            return false;
        return isCorrect(toReplace, replacement, toAdd, toAdd2);
    }

private boolean isCorrect(String toReplace, String replacement, String toAdd, String toAdd2) {
    String newText = getText().replace(toReplace,  replacement);
    if (Arrays.stream(newText.split(" "))
            .filter(w -> {
                return w.contains(replacement) && AlphabeticalStatistics.needsNoLetters(w);
            })
            .noneMatch(w -> {
                return !EnglishDeterminer.isWord(w);
            })
            ) {
        setText(newText);
        solvedLetters.add(toAdd);
        replacedLetters.add(toAdd2);
        return true;
    }
    return false;
}

Le but de ce programme est de déchiffrer un texte chiffré de substitution.

0
Marvin 15 févr. 2020 à 00:56

1 réponse

Meilleure réponse

Je semble plus rapide avec la boucle for indexée (for int i=0; i<size; i++). La suppression est probablement aussi plus rapide par index, car vous n'avez pas besoin de comparer les valeurs de votre collection pour trouver la correspondance. Vous devriez peut-être extraire une variable pour modifiableCollection.size() car elle sera évaluée à chaque itération.

 public static final int ITERATIONS = 100000000;

 public static void main(String[] args) {
    List<Character> alphabetList = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmopqrstuvwxyz123456789".chars()
            .mapToObj(c -> Character.valueOf((char) c)).collect(Collectors.toList());
    ArrayList<Character> copy = new ArrayList<>(alphabetList);
    List<Character> unmodifiableAlphabetList = Collections.unmodifiableList(copy);

    double timeA = checkTime(ITERATIONS, () -> {
        List<Character> modifiableCollection = new ArrayList<>(alphabetList);
        modifiableCollection.removeIf(next -> checkRemove(next));
    });
    System.out.println("A : " + timeA);

    double timeB = checkTime(ITERATIONS, () -> {
        List<Character> modifiableCollection = new ArrayList<>(alphabetList);
        Iterator<Character> iterator = modifiableCollection.iterator();
        while (iterator.hasNext()) {
            if (checkRemove(iterator.next())) {
                iterator.remove();
                break;
            }
        }
    });
    System.out.println("B : " + timeB);

    double timeC = checkTime(ITERATIONS, () -> {
        List<Character> modifiableCollection = new ArrayList<>(alphabetList);
        int size = modifiableCollection.size();
        for (int i = 0; i < size; i++) {
            Character character = unmodifiableAlphabetList.get(i);
            if (checkRemove(character)) {
                modifiableCollection.remove(i);
                break;
            }
        }
    });
    System.out.println("C : " + timeC);

    double timeD = checkTime(ITERATIONS, () -> {
        List<Character> modifiableCollection = new ArrayList<>(alphabetList);
        for (Character c : unmodifiableAlphabetList) {
            if (checkRemove(c)) {
                modifiableCollection.remove(c);
                break;
            }
        }
    });
    System.out.println("D : " + timeD);
}

private static boolean checkRemove(Character next) {
    return next.equals('W');
}

private static double checkTime(long count, Runnable fn) {
    List<Long> diffs = new ArrayList<>();

    for (int i = 0; i < count; i++) {
        long now = System.nanoTime();
        fn.run();
        long after = System.nanoTime();
        long nanoDiff = after - now;
        diffs.add(nanoDiff);
    }
    double average = diffs.stream()
            .mapToLong(l -> l)
            .average()
            .orElse(0L);
    return average;
}

A : 247.68729885
B : 83.9981085
C : 63.98897325
D : 91.69348503
1
cghislai 15 févr. 2020 à 00:38