J'essaie d'implémenter une fonction qui recherche une chaîne donnée et inverse la capitalisation de toutes les occurrences de caractères alphabétiques particuliers (insensible à la casse), laissant les nombres, les caractères spéciaux et autres caractères alphabétiques inchangés.
Par exemple, si theString = "abc123XYZ" et reverseCaps = "cyz", le résultat devrait être "abC123Xyz".
J'ai essayé diverses implémentations et correctifs, mais je n'arrive pas à le faire fonctionner correctement. Le résultat que j'obtiens maintenant est "ABC123xyz".
Voici mon code:
public static String flipCaseChars(String theString, String reverseCap) {
StringBuilder buf = new StringBuilder(theString.length());
for (int i = 0; i < theString.length(); i++) {
char c = theString.charAt(i);
if (Character.isUpperCase(c)) {
buf.append(Character.toLowerCase(c));
}
else if (Character.isLowerCase(c)) {
buf.append(Character.toUpperCase(c));
}
// if char is neither upper nor lower
else {
buf.append(c);
}
}
return buf.toString();
}
Que dois-je faire? Toute aide serait très appréciée.
5 Réponses :
Un moyen plus simple consiste à parcourir la chaîne reverseCap et à effectuer un remplacement conditionnel
for (char c : reverseCap.toCharArray()) {
if (Character.isLowerCase(c)) {
theString = theString.replace(c, Character.toUpperCase(c));
}
else {
theString = theString.replace(c, Character.toLowerCase(c));
}
}
return theString;
public static String flipCaseChars(String theString, String reverseCap) {
StringBuilder buf = new StringBuilder(theString.length());
for (int i = 0; i < theString.length(); i++) {
char c = theString.charAt(i);
if (reverseCap.indexOf(c) >= 0){
if (Character.isUpperCase(c)) {
buf.append(Character.toLowerCase(c));
} else if (Character.isLowerCase(c)) {
buf.append(Character.toUpperCase(c));
} else {
buf.append(c);
}
} else {
buf.append(c);
}
}
return buf.toString();
}
@ScaryWombat, il est en effet nécessaire car la fonction renvoie buf.
Désolé mon mauvais.
Merci. Cela fonctionne presque. Le résultat que j'obtiens maintenant est "abC123XYZ". Il semble qu'il n'inverse pas la capitalisation sur Y ou Z car l'entrée pour reverseCap est entièrement en minuscules. Si je change l'entrée en reverseCap = "cYZ", cela fonctionne correctement. Comment ce code peut-il être modifié pour que les lettres à inverser soient insensibles à la casse?
Inutile de vérifier si le caractère est en majuscules ou en minuscules. Il retourne simplement la casse du personnage comme il convient. Cela suppose que la liste inversée de caractères est entièrement en minuscules, comme indiqué dans l'exemple.
Cela fonctionne en vérifiant puis en manipulant le bit 0x20 qui détermine les majuscules et les minuscules en caractères ASCII. p>
Le ^ est l'opérateur OU exclusif qui bascule vers le cas contraire en retournant le bit de casse.
public static String flipCaseChars(String theString, String reverseCap) {
StringBuilder sb = new StringBuilder();
for (char c : theString.toCharArray()) {
// is the character in the list?
if (reverseCap.indexOf(c | 0x20) >= 0) {
c ^= 0x20; // flip the case
}
sb.append(c);
}
return sb.toString();
}
J'ai essentiellement créé un HashSet de reverseCap , puis le reste suit Réponse de @ toootooo
Le voici:
static String flipCaseChars(String theString, String reverseCap) {
final StringBuilder stringBuilder = new StringBuilder(theString.length());
HashSet<Character> collect = new HashSet<>();
for (int i = 0; i < reverseCap.length(); i++) {
collect.add(Character.toLowerCase(reverseCap.charAt(i)));
collect.add(Character.toUpperCase(reverseCap.charAt(i)));
}
for (int i = 0; i < theString.length(); i++) {
char currentChar = theString.charAt(i);
if (collect.contains(currentChar)) {
if (Character.isUpperCase(currentChar)) {
currentChar = Character.toLowerCase(currentChar);
} else if (Character.isLowerCase(currentChar)){
currentChar = Character.toUpperCase(currentChar);
}
}
stringBuilder.append(currentChar);
}
return stringBuilder.toString();
}
Le seul avantage de cette approche est que la recherche des caractères dans reverseCap se fait en temps constant et la complexité temporelle est directement proportionnelle à la longueur de theString.
Est-ce que je manque quelque chose ici? Je vois que certaines réponses sont votées, mais elles ne font pas ce que le PO a demandé. D'après l'exemple d'entrée ( "abc123XYZ" ) et de sortie ( "abC123Xyz" ), je vois que la casse des caractères dans les reverseCaps n'est pas pertinente. Il peut s'agir de n'importe quelle casse, mais si l'une d'entre elles est rencontrée dans la chaîne d'entrée ( theString ) quel que soit l'état actuel de la casse des lettres, l'un des caractères fournis est la casse des lettres si elle est retournée à son «état opposé. Donc, si la chaîne d'entrée était: ab-c-123-C-XYz et que la variable reverseCaps contenait "cyz" , alors la variable la sortie doit être: ab-C-123-c-XyZ . Est-ce que je me trompe? Si je ne me trompe pas, le code suivant exécutera la tâche expliquée ci-dessus: public static String flipCaseCharacters(String inputString, String charactersToFlip) {
StringBuilder newString = new StringBuilder();
for (char inChar : inputString.toCharArray()) {
for (char ctFlip : charactersToFlip.toCharArray()) {
if (Character.toUpperCase(inChar) == Character.toUpperCase(ctFlip)) {
inChar = Character.isUpperCase(inChar) ?
Character.toLowerCase(inChar) :
Character.toUpperCase(inChar);
break;
}
}
newString.append(inChar);
}
return newString.toString();
}