Pages

2010年10月2日 星期六

Java String 依照單字出現次數/頻率高的依序印出

功能:
依照每個單字出現的次數,由大到小,排列印出。

假設:
String oriString = "This is a book. That is a pencil"

輸出:
is 出現 2 次
a 出現 2 次
This 出現 1 次
That 出現 1 次
book 出現 1 次
pencil 出現 1 次

程式碼:
import java.util.regex.*;
import java.util.*;

public class StringSort {
 public static void main(String[] args){
  String oriString = "This is a book. That is a pencil.";
  Pattern p = Pattern.compile("\\w[^\\.\\s]*");
  Matcher m = p.matcher(oriString);
  
  Set<string> sortVerb = new TreeSet<string>();
  ArrayList<string> strArray = new ArrayList<string>();
  while(m.find()){
   strArray.add(m.group());
   sortVerb.add(m.group());
  }

  //計算oriString中的各個單字的次數
  int[] verbCount = new int[sortVerb.size()];
  int index = 0;
  for(String s : sortVerb){
   int count = 0;
   for(String sr : strArray){
    if(s.equals(sr))
     count++;
   }
   verbCount[index++] = count;
  }

  //開始排序
  int[] indexArray = new int[sortVerb.size()];
  for(int i = 0; i < indexArray.length; i++)
   indexArray[i] = i;
  int temp, indexTemp;
  index = 0;
  for (int f = 1; f < sortVerb.size(); f++) {
      if (verbCount[f] < verbCount[f-1])
       continue;
      temp = verbCount[f];
      indexTemp = indexArray[f];
      index = f-1;
      while ((index >= 0)&&(verbCount[index] < temp)) {
       verbCount[index+1] = verbCount[index];
       indexArray[index+1] = indexArray[index];
       index--;
      }
      verbCount[index+1]=temp;
      indexArray[index+1] = indexTemp;
  }
  Object[] printStr = sortVerb.toArray();
  for(int i = 0; i < indexArray.length; i++)
   System.out.println(printStr[indexArray[i]].toString()+"出現 "+verbCount[i]+"次");
 }
}

執行結果:
a出現 2次
is出現 2次
That出現 1次
This出現 1次
book出現 1次
pencil出現 1次

Linking-List Implement

[轉載] from: http://www.cnblogs.com/oomusou/archive/2008/03/22/1117686.html
Abstraction
使用C語言簡單的實現linked list,並用C++的std::vector實作出相同的功能作比較。
Introduction
學習資料結構,第一個要學的就是linked list,本文示範最簡單的linked list實現,包含建立與顯示,可把它當成linked list的標準範本,畢竟步驟都差不多。
一個基本的問題:為什麼需要linked list?若要將大量資料存到記憶體,你會想到什麼?第一個想到的就是array,但C語言是個靜態語言,array必須事先宣告大小,這樣compiler才能進行最佳化,若到時候沒用這麼多記憶體,就白白浪費記憶體了。或許你會說array可以配合malloc()變成動態array,但前提是你必須告訴malloc()要建立多大的array,若連要建立多大的陣列也不確定,而是在run-time看有多少資料就建立多大,這時連malloc()的動態array也不能用了,此時就得靠linked list。
linked list是資料結構的基礎,基本上就是靠struct如火車車廂那樣連在一起,run-time有需要時,在動態掛一個struct上去。

For C語言:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SLEN 255

struct list {
  int  no;
  char name[SLEN];
  struct list *next;
};
int main() {
  int no;
  char s[255];
  struct list *head    = NULL;
  struct list *current = NULL;
  struct list *prev    = NULL;

  while(1) {
    printf("No. = ");
    scanf("%d", &no);
    if (no == 0)
      break;

    printf("Name = ");
    scanf("%s", s);

    current = (struct list *)malloc(sizeof(struct list));
    if (current == NULL)
      exit(EXIT_FAILURE);

    current->next = NULL;

    current->no = no;
    strncpy(current->name, s, SLEN -1);
    current->name[SLEN -1] = '\0';

    if (head == NULL)
      head = current;
    else
      prev->next = current;

    prev = current;
  }

  // display linked list
  current = head;
  while(current != NULL) {
    printf("No. = %d, Name = %s\n", current->no, current->name);
    current = current->next;
  }

  // free linked list
  current = head;
  while(current != NULL) {
    prev = current;
    current = current->next;
    free(prev);
  }
  return 0;
}
執行結果:
1
ssss
2
kkkk
3
gggg
4
llll
0
No. = Name = No. = Name = No. = Name = No. = Name = No. = No. = 1, Name = ssss
No. = 2, Name = kkkk
No. = 3, Name = gggg
No. = 4, Name = llll
好吧,我承認怪怪的,可以Work了!

For C++:
#include <iostream>
#include <string>
#include <vector>

using namespace std;

class List {
public:
  int no;
  string name;
};

int main() {
  vector<list> vec;

  while(1) {
    List list;
    cout << "No. = ";
    cin >> list.no;

    if (list.no == 0)
      break;

    cout << "Name = ";
    cin >> list.name;

    vec.push_back(list);
  }

  vector<list>::iterator iter = vec.begin();
  for(; iter != vec.end(); ++iter)
    cout << "No. = " << iter->no << ", Name = " << iter->name << endl;
  return 0;
}

C++看起來簡單多了!

C語言指標範例(指標++)

C語言中最令初學者人頭大的指標,其實很容易記錯
指標的運算元順序是由右到左(書上寫的),實際來測試一下

#include<stdio.h>
int data[2] = {100,200};
int moredata[2] = {300,400};
int main(void){
 int * p1, * p2, * p3;
 p1 = p2 = data;
 p3 = moredata;
 printf(" *p1 = %d, *p2 = %d, *p3= %d\n",
   *p1, *p2, *p3);
 printf(" *p1 = %d, *p2 = %d, *p3= %d\n",
   *p1++, *++p2, (*p3)++);
 printf(" *p1 = %d, *p2 = %d, *p3= %d\n",
   *p1, *p2, *p3);
 //括號測試
 printf("It is equal result...\n");
 p1 = p2 = data;
 p3 = moredata;
 printf(" *p1 = %d, *p2 = %d, *p3= %d\n",
    *(p1++), *(++p2), (*p3)++);
 printf(" *p1 = %d, *p2 = %d, *p3= %d\n",
   *p1, *p2, *p3);
  return 0;
}

*p1 = 100, *p2 = 100, *p3= 300
 *p1 = 100, *p2 = 200, *p3= 300
 *p1 = 200, *p2 = 200, *p3= 301
It is equal result...
 *p1 = 100, *p2 = 200, *p3= 301
 *p1 = 200, *p2 = 200, *p3= 302

由此得知,*p1++ 相等於 *(p1++)
而不是(*p)++,我之前記錯了><

C/C++[微小位元][數字&數字]

最近,因為面試的關係,想把一些東西弄清楚,所以做了一些測試:
以下是微小位元的測試,實際是就是二進位運算啦,考是算錯(怪怪)

#include<stdio.h>

int main(void){
  int a = 44;
  int b = 55;
  int c = 33;
  int d = -20;
  printf("uni-micro operator: \n");
  printf("a & b = %d\n", a & b);
  printf("b & c = %d\n", b & c);
  printf("c & d = %d\n", c & d);
  printf("b & b = %d\n", b & b);
  printf("a | b = %d\n", a | b);

  printf("double-micro operator: \n");
  printf("a && b = %d\n", a && b);
  printf("a || b = %d\n", a || b);

  printf("while-micro operator: \n");
  while( a & b){
   printf("a ^ b = %d, ", a ^ b);
   a--;
   if(a < 40){
    break;
   }
  }
  printf("\n");
  while( a ^ d){
     printf("a ^ d = %d, ", a ^ d);
     a--;
     if( a ^ d < 0){
      break;
     }
  }

  return 0;
}
結果:
uni-micro operator: 
a & b = 36
b & c = 33
c & d = 32
b & b = 55
a | b = 63
double-micro operator: 
a && b = 1
a || b = 1
while-micro operator: 
a ^ b = 27, a ^ b = 28, a ^ b = 29, a ^ b = 30, a ^ b = 31, 
a ^ d = -53, 

由結果知道,while迴圈對負號的數值也會進入迴圈跑,我之前已為負的就不會跑= ="
學習中...

2010年2月2日 星期二

解決C/C++中的multiple definition of問題

範例:
main.cpp

#include "global.h" 
int Main(....) { ... }

file_1.cpp

#include "global.h"
....

file_1.cpp

#include "global.h" 

global.h中寫有所有的全局變量及其初始化值和函數聲明
在編譯的時候就會出錯: first defined here multiple definition of
原因是因為在多次包含global.h時重複定義了變量和函數。
解決方法: 


方法一:

在global.c(或.cpp) 中聲明變量(不初始化),然後頭文件global.h中在所有的變量聲明前加上extern 如 extern int flag; 然後在其他需要使用全局變量的cpp文件中包含.h 文件而不要包含.cpp 文件。編譯器會為global.cpp 生成目標文件,然後連接時,在使用全局變量的文件中就會連接到此文件。 

範例:

Declare.h:
#ifndef DECLARE_H
#define DECLARE_H
extern const char *COMP;
#endif

subprog.cpp:
#include 
#include "Declare.h"
const char *COMP="macromedia";

void ShowComp() {
std::cout << COMP << std::endl;
}
main.cpp:
#include "Declare.h"
extern void ShowComp();
int main(int agrc, char *argv[]) {
ShowComp();
return 0;
}
方法二: 在global.h中加入防止多次重複定義的宏判斷符號 你的.H裡面要加上條件編譯 #ifndef GLOBAL #define GLOBAL XXXXX XXXXX  ...................... #endif   記住:在ifndef時一定要在第一行,前邊不要有任何的註釋或語句。

2010年1月26日 星期二

vector傳遞/宣告(struct/物件)以及iterator 範例

轉載[http://www.cnblogs.com/oomusou/archive/2008/08/01/vector_struct.html]

Abstract
一個很常見的需求:『將struct塞進vector』,在C++該怎麼做呢?
Introduction
使用環境:Visual C++ 9.0 / Visual Studio 2008

由於vector只允許一個欄位,所以才會想將struct塞進vector,以彌補vector的不足。
struct_in_vector.cpp / C++
/*
  (C) OOMusou 2008 http://oomusou.cnblogs.com
 
  Filename    : struct_in_vector.cpp
  Compiler    : Visual C++ 9.0 / Visual Studio 2008
  Description : Demo how to insert struct in vector
  Release     : 08/01/2008 1.0
  */

 #include <iostream>
 #include <vector>
 #include <string>

 using namespace std;
 
 struct Student {
   int  id;
   string name;
 };
 
 int main() {
   vector svec;
   
   struct Student master;
   master.id = 1;
   master.name = "clare";
   svec.push_back(master);
   
   master.id = 2;
   master.name = "jingyi";
   svec.push_back(master);
   
   master.id = 3;
   master.name = "jessie";
   svec.push_back(master);
   
   vector::iterator iter = svec.begin();
   for(iter; iter != svec.end(); ++iter)
     cout << iter->id << " " << iter->name << endl;
 }
執行結果
clare
jingyi
jessie
由於vector內放的是struct,所以push_back()要塞個也是struct,而不能針對struct的member來塞。因此要先宣告一個暫存的struct做中介。
以上的code,看起來都是push_back()同一個master object,這樣沒有問題嗎?因為push_back()進vector是採用copy的方式,會產生一個新的副本,所以才可以這樣使用。

vector內元件刪除

 C++中 vector內元素刪除的方法分為兩個~
方法1:
vector<AA>::iterator ite;
for ( ite = vaa.begin(); ite != vaa.end(); )
{
    if (find(intList.begin(), intList.end(),ite->n) != intList.end())
        vaa.erase(++ite);
    else
        ++ite;
}


方法2:
vector<AA>::iterator ite = vaa.begin();
for (ite = vaa.begin(); ite != vaa.end(); ++ite )
{
    if (find(intList.begin(), intList.end(),ite->n) != intList.end())
        vaa.erase(ite);
}

當vector內是物件或是struct時,以上的方法可能會有錯誤,這是因為當
erase時,iterator就會失效,因此可以用下面的方式解決

方法3:
struct AA{
    int a;
    int b;
    int (int x, y){a=x;b=y;}

}

vector<struct AA>::iterator ite = vaa.begin();
for (ite = vaa.begin(); ite != vaa.end(); ++ite )
{
    if (判斷式)
        ite = vaa.erase(ite);
    else
        ++ite;
}

簡單的方法大致如上,其實有其他更好的方法,不過有些複雜像是if_find搭
配#include裡面所定義的方法可以讓vector<物件>刪除更容易

2010年1月23日 星期六

Java判斷作業系統與檔案路徑

如何在java程式中判斷幕前作業系統是何種作業系統
以下位範例程式:
public class OSValidator {

    public static void main(String[] args) {
        if (isWindows()) {
            System.out.println("This is Windows");
        } else if (isMac()) {
            System.out.println("This is Mac");
        } else if (isUnix()) {
            System.out.println("This is Unix or Linux");
        } else {
            System.out.println("Your OS is not support!!");
        }
    }

    public static boolean isWindows() {

        String os = System.getProperty("os.name").toLowerCase();
//windows
        return (os.indexOf("win") >= 0);

    }

    public static boolean isMac() {

        String os = System.getProperty("os.name").toLowerCase();
//Mac
        return (os.indexOf("mac") >= 0);

    }

    public static boolean isUnix() {

        String os = System.getProperty("os.name").toLowerCase();
//linux or unix
        return (os.indexOf("nix") >= 0 || os.indexOf("nux") >= 0);

    }
}
System.getProperty("os.name") 在java程式中判斷此作業系統是Linux或Windows
在Ubuntu的作業系統中,測試取的的字串為Linux,vista則為Windows。


System.getProperty("file.separator")  => 使用時機是在需要用到路徑的時候,Windows使用 "\\",或Linux使用 "/"
來建立檔案或資料夾路徑。