web-dev-qa-db-fra.com

Ecrivez une méthode pour remplacer tous les espaces d'une chaîne par '% 20'

J'ai une question sur un problème de programmation de l'ouvrage Cracking The Code Interview réalisé par Gayl Laakmann McDowell, 5ème édition.

Le problème est le suivant: Ecrivez une méthode pour remplacer tous les espaces d'une chaîne par '% 20'. Supposons que la chaîne a suffisamment d’espace à la fin de la chaîne pour contenir des caractères supplémentaires et que la longueur réelle de la chaîne vous est attribuée. J'ai utilisé le code du livre en implémentant la solution en Java à l'aide d'un tableau de caractères (étant donné que les chaînes de caractères Java sont immuables):

public class Test {
    public void replaceSpaces(char[] str, int length) {
        int spaceCount = 0, newLength = 0, i = 0;

        for(i = 0; i < length; i++) {
            if (str[i] == ' ') 
                spaceCount++;
        }

        newLength = length + (spaceCount * 2);
        str[newLength] = '\0';
        for(i = length - 1; i >= 0; i--) {
            if (str[i] == ' ') {
                str[newLength - 1] = '0';
                str[newLength - 2] = '2';
                str[newLength - 3] = '%';
                newLength = newLength - 3;
            }
            else {
                str[newLength - 1] = str[i];
                newLength = newLength - 1;
            }
        }
        System.out.println(str);
    }

    public static void main(String[] args) {
        Test tst = new Test();
        char[] ch = {'t', 'h', 'e', ' ', 'd', 'o', 'g', ' ', ' ', ' ', ' ', ' ', ' '};
        int length = 6;
        tst.replaceSpaces(ch, length);  
    }
}

Le résultat de l'appel replaceSpaces() que je reçois est: le% 20do qui coupe le dernier caractère du tableau d'origine. Je me suis gratté la tête à ce sujet. Quelqu'un peut-il m'expliquer pourquoi l'algorithme le fait?

13
user753986

Vous passez la longueur en tant que 6, ce qui provoque ceci. La longueur du passage est de 7, espace compris. Autrement

for(i = length - 1; i >= 0; i--) {

ne considérera pas le dernier caractère.

7
jaxb
public String replace(String str) {
    String[] words = str.split(" ");
    StringBuilder sentence = new StringBuilder(words[0]);

    for (int i = 1; i < words.length; ++i) {
        sentence.append("%20");
        sentence.append(words[i]);
    }

    return sentence.toString();
}
8
Victor

Avec ces deux modifications, j'ai obtenu le résultat: the% 20dog

1) Définissez le nombre d'espaces sur 2 [car la longueur inclut déjà l'un des 3 caractères nécessaires pour% 20]

newLength = length + (spaceCount * 2);

2) La boucle devrait commencer sur la longueur

for(i = length; i >= 0; i--) {
4
Jarle Hansen

Ceci est mon code pour cette question. On dirait travailler pour moi. Si cela vous intéresse, jetez un coup d'oeil. C'est écrit en Java

public class ReplaceSpaceInString {
  private static char[] replaceSpaceInString(char[] str, int length) {
    int spaceCounter = 0;

    //First lets calculate number of spaces
    for (int i = 0; i < length; i++) {
      if (str[i] == ' ') 
        spaceCounter++;
    }

    //calculate new size
    int newLength = length + 2*spaceCounter;

    char[] newArray = new char[newLength+1];
    newArray[newLength] = '\0';

    int newArrayPosition = 0;

    for (int i = 0; i < length; i++) {
      if (str[i] == ' ') {
        newArray[newArrayPosition] = '%';
    newArray[newArrayPosition+1] = '2';
    newArray[newArrayPosition+2] = '0';
    newArrayPosition = newArrayPosition + 3;
      }
      else {
    newArray[newArrayPosition] = str[i];
    newArrayPosition++;
      }
    }               
    return newArray;
  }

  public static void main(String[] args) {
    char[] array = {'a','b','c','d',' ','e','f','g',' ','h',' ','j'};
    System.out.println(replaceSpaceInString(array, array.length));
  }
}
2
Amarjit Datta

Voici ma solution. Je vérifie le code ASCII 32, puis je mets un% 20 à la place de celui-ci. La complexité temporelle de cette solution est O (N).

public String replace(String s) {

        char arr[] = s.toCharArray();
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == 32)
                sb.append("%20");
            else
                sb.append(arr[i]);

        }

        return sb.toString();
    }

Vous pouvez également utiliser la méthode substring et l’ascii pour obtenir de l’espace (32).

public String replaceSpaceInString(String s){
    int i;
    for (i=0;i<s.length();i++){
        System.out.println("i is "+i);
        if (s.charAt(i)==(int)32){
            s=s.substring(0, i)+"%20"+s.substring(i+1, s.length());
            i=i+2;              
            }
    }
    return s;
    }

Tester:

System.out.println(cc.replaceSpaceInString("mon day "));

Sortie:

mon%20day%20
1
uoftcode

Nous pouvons utiliser une expression régulière pour résoudre ce problème. Par exemple:

public String replaceStringWithSpace(String str){
     return str.replaceAll("[\\s]", "%20");
 }
1
Intelligent

S'agit-il de questions d'entretien?

Dans la programmation du monde réel, je suggérerais: URLEncoder.encode ()

1

Vous pouvez simplement faire ça. Pas besoin de calculer la longueur ou autre chose. Les cordes sont immuables de toute façon.

import Java.util.*;
public class ReplaceString {

    public static void main(String[] args) {
        Scanner in=new Scanner(System.in);
        String str=in.nextLine();
        String n="";
        for(int i=0;i<str.length();i++)
        {
            if(str.charAt(i)==' ')
                n=n+"%20";
            else
                n=n+str.charAt(i);
        }
        str=n;
        System.out.println(str);
    }
}
1
rohit
void Rep_Str(char *str)
{
    int j=0,count=0;
    int stlen = strlen(str);
    for (j = 0; j < stlen; j++)
    {
        if (str[j]==' ')
        {
            count++;
        }
    }

    int newlength = stlen+(count*2);
    str[newlength--]='\0';
    for (j = stlen-1; j >=0 ; j--)
    {
        if (str[j]==' ')
        {
            str[newlength--]='0';
            str[newlength--]='2';
            str[newlength--]='%';
        }

        else
        {

            str[newlength--]=str[j];
        }
    }
}

Ce code fonctionne :)

1
user3160383

Hm ... Je m'interroge également sur ce problème. Compte tenu de ce que j'ai vu ici. La solution de livre ne convient pas à Java car elle utilise in-situ

 char []

les modifications et les solutions ici qui utilisent char [] ou return void ne conviennent pas aussi bien, car Java n'utilise pas de pointeur.

Alors je pensais, la solution évidente serait

private static String encodeSpace(String string) {
     return string.replcaceAll(" ", "%20");
} 

mais ce n'est probablement pas ce que votre intervieweur aimerait voir :)

// make a function that actually does something
private static String encodeSpace(String string) {
     //create a new String
     String result = new String();
     // replacement
     final String encodeSpace = "%20";

     for(char c : string.toCharArray()) {
         if(c == ' ') result+=encodeString;
         else result+=c;
     }

     return result;
}

cela a l'air bien, pensais-je, et il ne faut qu'un seul passage dans la chaîne, la complexité devrait donc être O (n), non? Faux! Le problème est dans

result += c;

qui est le même que

result = result + c;

qui copie réellement une chaîne et en crée une copie. En Java, les chaînes sont représentées par

private final char value[];

ce qui les rend immuables (pour plus d’informations, je voudrais vérifier Java.lang.String et comment cela fonctionne). Ce fait va alourdir la complexité de cet algorithme en O (N ^ 2) et un recruteur sournois peut l'utiliser pour vous faire échouer: P Ainsi, je suis arrivé avec une nouvelle solution de bas niveau que vous n'utiliserez jamais dans la pratique, mais ce qui est bon en théorie :)

private static String encodeSpace(String string) {

    final char [] original = string != null? string.toCharArray() : new char[0];
    // ASCII encoding
    final char mod = 37, two = 50, zero = 48, space = 32;
    int spaces = 0, index = 0;

    // count spaces 
    for(char c : original) if(c == space) ++spaces; 

    // if no spaces - we are done
    if(spaces == 0) return string;

    // make a new char array (each space now takes +2 spots)
    char [] result = new char[string.length()+(2*spaces)];

    for(char c : original) {
        if(c == space) {
            result[index] = mod;
            result[++index] = two;
            result[++index] = zero;
        }
        else result[index] = c;
        ++index;
    }

    return new String(result);
}
0
EliK
public class ReplaceChar{

 public static void main(String []args){
   String s = "ab c de  ";
   System.out.println(replaceChar(s));

 }

 public static String replaceChar(String s){

    boolean found = false;
    StringBuilder res = new StringBuilder(50);
    String str = rev(s);
    for(int i = 0; i <str.length(); i++){

        if (str.charAt(i) != ' ')  { found = true; }
        if (str.charAt(i) == ' '&& found == true) { res.append("%02"); }            
        else{ res.append(str.charAt(i)); }
    }
        return rev(res.toString()); 
 }

 // Function to reverse a string
 public static String rev(String s){
     StringBuilder result = new StringBuilder(50);
     for(int i = s.length()-1; i>=0; i-- ){
        result.append(s.charAt(i));
    }
    return result.toString();
 }}

Une approche simple:

  1. Inverser la chaîne donnée et vérifier où le premier caractère apparaît.
  2. Utilisation du générateur de chaînes pour ajouter "02%" aux espaces, car la chaîne est inversée.
  3. Enfin, inversez à nouveau la chaîne.

Remarque: nous inversons la chaîne afin d'éviter l'ajout de "% 20" aux espaces de fin.

J'espère que cela pourra aider!

0
bharat nc

Une autre façon de faire ça. Je suppose que les espaces de fin n'ont pas besoin d'être convertis en% 20 et que ceux-ci offrent suffisamment de place pour que 20% soient remplis

public class Main {

   public static void main(String[] args) {

      String str = "a sd fghj    ";
      System.out.println(replacement(str));//a%20sd%20fghj
   }

   private static String replacement(String str) {
      char[] chars = str.toCharArray();
      int posOfLastChar = 0;
      for (int i = 0; i < chars.length; i++) {
         if (chars[i] != ' ') {
            posOfLastChar = i;
         }
      }

      int newCharPosition = chars.length - 1;

      //Start moving the characters to th end of the array. Replace spaces by %20
      for (int i = posOfLastChar; i >= 0; i--) {

         if (chars[i] == ' ') {
            chars[newCharPosition] = '0';
            chars[--newCharPosition] = '2';
            chars[--newCharPosition] = '%';
         } else {
            chars[newCharPosition] = chars[i];
         }

         newCharPosition--;
      }

      return String.valueOf(chars);
   }
}
0
developer747

La question dans le livre mentionne que le remplacement doit être en place de sorte qu'il ne soit pas possible d'affecter des tableaux supplémentaires, il doit utiliser un espace constant. Vous devez également prendre en compte de nombreux cas Edge, voici ma solution:

public class ReplaceSpaces {

    public static void main(String[] args) {
        if ( args.length == 0 ) {
            throw new IllegalArgumentException("No string");
        }
        String s = args[0];
        char[] characters = s.toCharArray();

        replaceSpaces(characters);
        System.out.println(characters);
    }

    static void replaceSpaces(char[] s) {
        int i = s.length-1;
        //Skipping all spaces in the end until setting `i` to non-space character
        while( i >= 0 && s[i] == ' ' ) { i--; }

        /* Used later to check there is enough extra space in the end */
        int extraSpaceLength = s.length - i - 1;

        /* 
        Used when moving the words right, 
        instead of finding the first non-space character again
        */
        int lastNonSpaceCharacter = i;

        /*
        Hold the number of spaces in the actual string boundaries
        */
        int numSpaces = 0;

        /*
        Counting num spaces beside the extra spaces
        */
        while( i >= 0 ) { 
            if ( s[i] == ' ' ) { numSpaces++; }
            i--;
        }

        if ( numSpaces == 0 ) {
            return;
        }

        /*
        Throw exception if there is not enough space
        */
        if ( extraSpaceLength < numSpaces*2 ) {
            throw new IllegalArgumentException("Not enough extra space");
        }

        /*
        Now we need to move each Word right in order to have space for the 
        ascii representation
        */
        int wordEnd = lastNonSpaceCharacter;
        int wordsCounter = 0;

        int j = wordEnd - 1;
        while( j >= 0 ) {
            if ( s[j] == ' ' ){
                moveWordRight(s, j+1, wordEnd, (numSpaces-wordsCounter)*2);         
                wordsCounter++;
                wordEnd = j;
            }
            j--;
        }

        replaceSpacesWithAscii(s, lastNonSpaceCharacter + numSpaces * 2);

    }

    /*
    Replaces each 3 sequential spaces with %20
    char[] s - original character array
    int maxIndex - used to tell the method what is the last index it should
    try to replace, after that is is all extra spaces not required
    */
    static void replaceSpacesWithAscii(char[] s, int maxIndex) {
        int i = 0;

        while ( i <= maxIndex ) {
            if ( s[i] ==  ' ' ) {
                s[i] = '%';
                s[i+1] = '2';
                s[i+2] = '0';
                i+=2;
            } 
            i++;
        }
    }

    /*
    Move each Word in the characters array by x moves
    char[] s - original character array
    int startIndex - Word first character index
    int endIndex - Word last character index
    int moves - number of moves to the right
    */
    static void moveWordRight(char[] s, int startIndex, int endIndex, int moves) {

        for(int i=endIndex; i>=startIndex; i--) {
            s[i+moves] = s[i];
            s[i] = ' ';
        }

    }

}
0
Matan Hafuta

Cela fonctionne correctement Cependant, l'utilisation d'un objet StringBuffer augmente la complexité de l'espace.

    Scanner scn = new Scanner(System.in);
    String str = scn.nextLine();
    StringBuffer sb = new StringBuffer(str.trim());

    for(int i = 0;i<sb.length();i++){
        if(32 == (int)sb.charAt(i)){
            sb.replace(i,i+1, "%20");
        }
    }
0
Sahib Bajaj

classe publique Sol {

public static void main(String[] args) {
    String[] str = "Write a method to replace all spaces in a string with".split(" ");
    StringBuffer sb = new StringBuffer();
    int count = 0;

    for(String s : str){
        sb.append(s);
        if(str.length-1 != count)
        sb.append("%20");
        ++count;
    }

    System.out.println(sb.toString());
}

}

0
sarfaraz pathan

Une raison de ne pas utiliser la méthode 'replace'?

 public String replaceSpaces(String s){
    return s.replace(" ", "%20");}
0
Boris
class Program
{
    static void Main(string[] args)
    {
        string name = "Stack Over Flow ";
        StringBuilder stringBuilder = new StringBuilder();

        char[] array = name.ToCharArray(); ;

        for(int i = 0; i < name.Length; i++)
        {
            if (array[i] == ' ')
            {
                stringBuilder.Append("%20");
            }
            else
                stringBuilder.Append(array[i]);
        }



        Console.WriteLine(stringBuilder);
        Console.ReadLine();

    }
}
0
Rock
public static String replaceAllSpaces(String s) {
    char[] c = s.toCharArray();
    int spaceCount = 0;
    int trueLen = s.length();
    int index = 0;
    for (int i = 0; i < trueLen; i++) {
        if (c[i] == ' ') {
            spaceCount++;
        }
    }
    index = trueLen + spaceCount * 2;
    char[] n = new char[index]; 
    for (int i = trueLen - 1; i >= 0; i--) {
        if (c[i] == ' ') {
            n[index - 1] = '0';
            n[index - 2] = '2';
            n[index - 3] = '%';
            index = index - 3;
        } else {
            n[index - 1] = c[i];
            index--;
        }
    }
    String x = new String(n);
    return x;
}
0
user2345051

Pouvez-vous utiliser StringBuilder?

public String replaceSpace(String s)
{
    StringBuilder answer = new StringBuilder();
    for(int i = 0; i<s.length(); i++)   
    {
        if(s.CharAt(i) == ' ')
        {
            answer.append("%20");
        }
        else
        {
            answer.append(s.CharAt(i));
        }
    }
    return answer.toString();
}
0
Ron Ghod

Question: Urlifiez les espaces avec% 20

Solution 1:

public class Solution9 {
public static void main(String[] args) {
    String a = "Gini Gina Protijayi";


       System.out.println(   urlencode(a));
}//main

public static String urlencode(String str) {
      str = str.trim();
        System.out.println("trim =>" + str);

        if (!str.contains(" ")) {
            return str;
        }

    char[] ca = str.toCharArray();

    int spaces = 0;
    for (char c : ca) {
        if (c == ' ') {
            spaces++;
        }
    }

    char[] newca = new char[ca.length + 2 * spaces];
      //  a pointer x has been added
    for (int i = 0, x = 0; i < ca.length; i++) {
        char c = ca[i];
        if (c == ' ') {
            newca[x] = '%';
            newca[x + 1] = '2';
            newca[x + 2] = '0';
            x += 3;
        } else {
            newca[x] = c;
            x++;
        }
    }
    return new String(newca);
}

}//urlify
0
Soudipta Dutta

Ma solution utilisant StringBuilder avec une complexité temporelle O (n)

public static String url(String string, int length) {
    char[] arrays = string.toCharArray();
    StringBuilder builder = new StringBuilder(length);

    for (int i = 0; i < length; i++) {
        if (arrays[i] == ' ') {
            builder.append("%20");
        } else {
            builder.append(arrays[i]);
        }
    }

    return builder.toString();
}

Cas de test :

@Test
public void testUrl() {
    assertEquals("Mr%20John%20Smith", URLify.url("Mr John Smith ", 13));
}
0
Sameer Shrestha

Je regarde aussi cette question dans le livre. Je crois que nous pouvons simplement utiliser String.trim() et String.replaceAll(" ", "%20) ici

0
Scorpio
public class Test {
    public static void replace(String str) {
        String[] words = str.split(" ");
        StringBuilder sentence = new StringBuilder(words[0]);

        for (int i = 1; i < words.length; i++) {
            sentence.append("%20");
            sentence.append(words[i]);
        }
        sentence.append("%20");
        System.out.println(sentence.toString());
    }
    public static void main(String[] args) {
        replace("Hello   World "); **<- Hello<3spaces>World<1space>**
    }
}

O/P :: Bonjour% 20% 20% 20World% 20

0
Suyash Nande

J'ai mis à jour la solution ici. http://rextester.com/CWAPCV11970

Si nous créons un nouveau tableau et non une transition sur place, pourquoi devons-nous marcher à reculons?

J'ai légèrement modifié la vraie solution pour avancer pour créer la chaîne cible encodée en URL.

Complexité temporelle:

  O(n) - Walking original string
  O(1) - Creating target string incrementally

  where 'n' is number of chars in original string

Complexité des espaces: O (n + m) - Dupliquer de l’espace pour stocker des espaces et des chaînes. où 'n' est le nombre de caractères dans la chaîne d'origine et 'm' est la longueur des espaces échappés

    public static string ReplaceAll(string originalString, char findWhat, string replaceWith)
    {
        var newString = string.Empty;
        foreach(var character in originalString)
            newString += findWhat == character? replaceWith : character + string.Empty;
        return newString;
    }
0

Mais je me demande ce qui ne va pas avec le code suivant:

private static String urlify(String originalString) {

        String newString = "";
        if (originalString.contains(" ")) {
            newString = originalString.replace(" ", "%20");
        }
        return newString;
    }
0
Jeena