Thursday, August 29, 2013

1.5 ------------------- string compress

Q:
1.5 Implement a method to perform basic string compression using the counts
of repeated characters. For example, the string “aabcccccaaa” would become
“a2blc5a3”. If the "compressed" string would not become smaller than the original string, your method should return the original string.


A:
public static String compressString(String str) {

    // assume str are all ASCII

    if (str == null)

        return null;

    // check there do not exist digits

    for (int i = 0; i < str.length(); i++)

        if (isDigit(str.charAt(i))) {

            System.err.println("inputs string exist Digits");

            System.exit(-1);

        }

    // count the repeated char number

    int[] charCount = new int[str.length()];

    char lastChar = str.charAt(0);

    for (int i = 1; i < str.length(); i++) {

        if (str.charAt(i) == lastChar)

            charCount[i] = charCount[i - 1] + 1;

        else

            lastChar = str.charAt(i);

    }

    // after counting , if at most two sequence,(i.e. no compress)

    // return original

    // now, this can be compressed

    StringBuffer sbf = new StringBuffer();

    for (int i = 0; i < str.length(); i++) {

        char ch = str.charAt(i);

        if (charCount[i] == 0)

            sbf.append(ch);

        // Then, we need add the digits, instead of chars

        while (i + 1 < str.length() && charCount[i + 1] > charCount[i]) {

            i++;

        }

        sbf.append(charCount[i] + 1);

    }

    String newStr = sbf.toString();

    if (newStr.length() >= str.length())

        return str;

    else

        return newStr;

}

private static boolean isDigit(char ch) {

    if (ch <= '9' && ch >= '0')

        return true;

    else

        return false;

}



  



Mistakes:
0:  一上来,题意没看清。    例子中,"b" 后面,压缩后,为1的。
  应该仔细看题的。----------> 面试时,应该重复听到的问题。 说出自己的理解。


1:  all objects should be checked "null" , otherwise, when running, there might be some nullPointerException.
2:   系统运行,遇到error,要打印提示,并跳出的语句不会。
          这是刚刚用到的。
               System.err.println("   error message      ");
                System.exit(-1);
3:   做循环的时候,应该先判断边界问题, 再去作别的判断。
例如,上面答案里: 
      while( charCount[i+1] > charCount[i] && i+1<str.length()  )      是不对的。会有边界溢出。
应该 while(i+1<str.length() && charCount[i+1] > charCount[i] )



学到:
1:       在paper上写完,一定要自己在脑子里,把各种情况都考虑一遍。
           例如,这里,就因为开始申请的chCount 全为零, 最后StringBuffer.add(count)的时候,要加1的。
2:   

1.4-------Replace space in char[]

Q:
Write a method to replace all spaces in a string with'%20'. You may assume that
the string has sufficient space at the end of the string to hold the additional
characters, and that you are given the "true" length of the string. (Note: if imple-menting in Java, please use a character array so that you can perform this opera-tion in place.)
EXAMPLE
Input: "Mr John Smith"
Output: "Mr%20Dohn%20Smith"


A:

static void replaceSpace(char[] ch, int n){

    // n is the number that actually saved in str

   

    //scan to count the number of space

    int numSpace = 0;

    for(int i = 0 ; i<n; i++){

        if(ch[i]==' ')numSpace++;

    }

    //reversely replace the tokens

    int numSpaceUnreplaced = numSpace;

    for (int i = n-1; i >= 0;i-- ){

        if(ch[i] != ' '){

            ch[i+2*numSpaceUnreplaced] = ch[i];

        }

        else{

            ch[i+2*numSpaceUnreplaced-2] = '%';

            ch[i+2*numSpaceUnreplaced-1] = '2';

            ch[i+2*numSpaceUnreplaced]   = '0';

            numSpaceUnreplaced--;

        }

    }

    System.out.println(ch);

}
Mistake:
1: 竟然不知道怎么声明 char 数组,  哎, 最后只能用String.toCharArray()来声明。
  应该是这样:

  char[] copyFrom = {'d', 'e', 'c', 'a', 'f', 'f', 'e',
            'i', 'n', 'a', 't', 'e', 'd'};

2:








1.3------- check if one string is the permutation of the other

Q:
 Given two strings, write a method to decide if one is a permutation of the other.

A:

public static boolean isPermutation(String str1, String str2){

    if (str1 == null && str2 == null)return true;         //both are not nulll

    else if (str1 == null || str2 == null)                       // only one is null

        return false;

    else{                                                                // both are not null ,  maybe of length 0

        if(str1.length()!= str2.length())

            return false;

        // Now they are of the same length, and

        char[] arr = str1.toCharArray();

        Arrays.sort(arr);

        str1 = new String(arr);

       

        arr = str2.toCharArray();

        Arrays.sort(arr);

        str2 = new String(arr);

        if(str1.equals(str2))    return true;

        else                return false;

    }

}




Mistakes
1: java里面, 没有elseif 语句, 只有 else if
2:   没有清楚, Arrays.sort(arr); 返回是void,  而所谓的排序,就是在arr里直接操作了。
    另外, 要import java.util.Arrays; 
 
3: 书上说“    in your interview, you should always check with your interviewer about the size of the character set."
4:   另外一个方法,就是  ”check if the two strings have identical character counts.

学到的


 可以看这里 java传值还是传引用
 
参见
http://www.javaresearch.org/article/3156.htm
1、对象是按引用传递的
2、Java 应用程序有且仅有的一种参数传递机制,即按值传递
3、按值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本
4、按引用传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本
写的没错,但是文字太多,第二条就已经把人弄糊涂了,得仔细看完4条才清楚。而且对String类型的疑惑没有解决。

这么简单的事情,何必这么绕呢?为啥没人跟c++过不去,偏要跟Java来劲?
三句话总结一下:
1.对象就是传引用
2.原始类型就是传值
3.String等immutable类型因为没有提供自身修改的函数,每次操作都是新生成一个对象,所以要特殊对待。可以认为是传值。
对于,String类型 ,可以看这里
说完了java的String类型,我们最后看看java函数参数的传递,到底是值传递还是引用传递呢?一般的说法是对于基本类型比如int、char是值传递,对于对象类型是引用传递。这种说法没错,但是请看下面的例子:
String s=”abc”;
change(s);
System.out.println(s);
public void change(String str)
{
     str=”abcd”;
}
上面的程序会有什么结果呢?打印abc还是abcd,运行程序会发现打印的是abc,完了,似乎不合乎常理,按理说String 也是对象,应该是引用传递才对啊,有的同学知道java的String类型是不可变类型,会得出结果abc,具体解释是String就相当于是char[]的包装类。包装类的特质之一就是在对其值进行操作时会体现出其对应的基本类型的性质。在参数传递时,包装类就是如此体现的。所以,对于String在这种情况下的展现结果的解释就自然而然得出了。同样的,Integer、Float等这些包装类和String在这种情况下的表现是相同的。下面从函数参数传递的方式来理解也可以得出相同的结果。
java的参数传递本质上都可以认为是值传递,对基本类型自然不必说,对于对象类型,传递的是对象的地址,地址是个数字,也是基本类型,所以也还是值传递的, 有了这个基础,上面的题目可以这样理解,s是字符串abc的地址,调用change方法时,把s的拷贝赋给str,即str也指向abc,但是在方法里又把str指向abcd,str就是abcd的地址了,但是s还是指向的abc。

1.2 ---- using C, reverse a null-terminated string

Q:
Implement a function void reverse(char* str) in C or C++ which reverses a null-
terminated string.
A:


1.1-------- check if a string has all unique characters

Q:
    implement an algorithm to determine if a string has all unique characters.

   What if you cannot use additional data structures?

A:
// (With additional structures.)

    public static boolean isUniq(String str){

        // assuming that the str chars are all ASCII character

        if (str == null && str.length()==0) return true;

        if (str.length() > 128) return false;

        int[] ascii= new int[128];

         char ch;

        for(int i = 0; i< str.length();i++ ){

ch = str.charAt(i);

            if (ascii[ch]>0) {

                return false;

            }else{

                ascii[ch]++;

            }

        }

        return true;
    }


Mistakes:
0:  最恶心的是, 上面的128,是ASCII码的数目吗?  明明应该是256,  日啊~~~~
1: Cannot make a static reference to the non-static method isUniq(String)
    either declare an object, or  use static

2:  having a returned data type in a method declaration, you MUST return something eventually.
    Even you returned somethig earlier,  but should also return something

3: 竟然在上面,忘了取出str的各个char 的值~~~~~~~~~~~~丢人

4:if (str == null && str.length()==0) return true;
    这里,&& 后面的str   “can only be null"
    而且,这里应该用或    ||   的,  逻辑混乱。   哎~~~

5:  ascii 用boolean格式,明显比 int 要好,又不是让你数数。 哎



改进:
1:    用 bitvector 代替boolean, 只用1/8的空间。
2:   如果假设仅仅是a-z的时候,只用一个int 类型, 4*8 = 32 个bit,就可以了。
             但,书里面的移位是啥意思?