More servicesWindows Live
Sign in
 
 
Spaces home  dy的共享空间PhotosProfileFriendsMore Tools Explore the Spaces community

dy的共享空间

forger GDI for JavaScript

/*
  title:  forger GDI for JavaScript;
  file:   gdi.js
  author: hpho
  create: 2008-08-10
  update:
*/
 
///////////////////
//基本数据结构
//
function HDC(h){
   h._hdc=this;
   this.hwnd=h;
   this.buffer="";
   this.X=0;
   this.Y=0;
   this.toString=function(){
     return this.buffer;
   }
}
 
function tagPOINT(){
   this.x;
   this.y;
}
 
function tagRECT(){
   this.left;
   this.top;
   this.right;
   this.bottom;
}
 
/////////////////
 //基本函数
//
 
function GetDC(hwnd){
   return new HDC(hwnd);
}
 
function ReleaseDC(hdc){
   hdc.hwnd._hdc=null;
   hdc.hwnd=null;
   hdc.buffer="";
}
 
function UpdateWindow(hwnd){
   hwnd.innerHTML=hwnd._hdc;
}
 
function RGB(r,g,b){
   var rz="",gz="",bz="";
  
   if(r==0)
     rz="0";
   if(g==0)
     gz="0";
   if(b==0)
     bz="0";
    
   return "#"+(r.toString(16)+rz)+
              (g.toString(16)+gz)+
              (b.toString(16)+bz);
}
 
function SetPixel(hdc,x,y,color){
   var c=".";
   if(color!=null){
      c="<font color='"+color+"'>"+c+"</font>";
   }
  
   hdc.buffer=hdc.buffer+
              "<div style='position:absolute;width:0.1px;height:0.1px;left:"+
              (hdc.X+x)+
              "px;top:"+
              (hdc.Y+y)+
              "px;'>"+
              c+
              "</div>";
}
 
function MoveToEx(hdc,x,y,pt){
   if(pt!=null){
      pt.x=hdc.X;
      pt.y=hdc.Y;
   }
  
   hdc.X=x;
   hdc.Y=y;
}
 
///////////////////////////////////////////////////////////////
// Sample  Code: gdi_test.html
///////////////////////////////////////////////////////////////
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                                 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <meta http-equiv="Content-Language" content="zh-cn">
    <title>gdi test</title>
    <script src="./gdi.js"></script>
</head>
<body>
<div id="my_view"></div>
<script>
function Radian(angle){
   return angle*Math.PI/180.0;
}
 
function Circle(hdc,r,color){
   var a=0;
   while(a<=360){
     x=r*Math.cos(Radian(a));
     y=r*Math.sin(Radian(a));
     SetPixel(hdc, x, y, color);
     a=a+1;
   }
}
 
var hdc=GetDC(my_view);
MoveToEx(hdc,100,100);
Circle(hdc, 30, RGB(0,0,255));
MoveToEx(hdc,160,100);
Circle(hdc, 30, RGB(0,0,0));
MoveToEx(hdc,220,100);
Circle(hdc, 30, RGB(255,0,0));
MoveToEx(hdc,130,130);
Circle(hdc, 30, RGB(255,255,0));
MoveToEx(hdc,190,130);
Circle(hdc, 30, RGB(0,255,0));
UpdateWindow(my_view);
</script>
</body>
</html>

using Lagrange Interpolation Polynomial replace 'switch'


#define BASEFUN(x,a,b,c,d) (((x-b)*(x-c)*(x-d))/((a-b)*(a-c)*(a-d)))
#define CALC(op, l, r) BASEFUN(op,'+','-','*','/')*(l+r)+ \
                       BASEFUN(op,'-','+','*','/')*(l-r)+ \
                       BASEFUN(op,'*','+','-','/')*(l*r)+ \
                       BASEFUN(op,'/','+','-','*')*(l/r)

int main(int argc,char *argv[])
{
 char op;
 float lv,rv;
 scanf("%f%c%f",&lv,&op,&rv);
 printf("%.3f%c%.3f=%.3f\n",lv,op,rv,CALC(op,lv,rv));
 return 0;
}

Permutation Algorithm

void permutable(char* str, int len, char* out, int j){ // 打印所有元素的全排列
 int i;
 char tmp;
 if(len>=1){
  for(i=0; i<len; ++i){
   tmp=*str;*str=str[i];str[i]=tmp;
   out[j]=*str;
   permutable(str+1, len-1,out,j+1);
   tmp=*str;*str=str[i];str[i]=tmp;
  }
  if(len==1){
   out[j+1]=0;
   printf("%s\n",out);
  }
 }
}
------------------------------------------------------------------------------------
算法正确性证明:
用归纳法,
设:S是不为空的集合, 表示为S = {e_1,e_2,...,e_n}; {n|1,2,3,...};
1,当有2个元素时,交换(e_1,e_2)便得到另一个排列(e_2,e_1),即2!=2.
2,设当N个元素时成立.
3,则若有N+1个元素时,在N+1中取e_1,
  做交换(e_1,e_x) ;{x|2...n+1}, 便有新的一个拥有N个元素的子集(e_1,e_3,...,e_n+1),
  这时会有N个不同的这样的子集且再加上原来(e_2,e_3...,e_n+1),共有N+1个大小为N个元素的子集.
  然后因为元素为N个时此作法成立(即(N+1)*N*...*1=n!), 因此算法得证#
因为N个元素时成立,所以算法得证#
 

用stl的函数推砌trim()函数

#include <algorithm>
#include <functional>
 
#include <string>
 
namespace hpho{
template<typename Bgn, typename End, typename T>
Bgn trim(Bgn bgn, End end, T v){
  using namespace std;
  typedef reverse_iterator<char*,char>  RIter;
  End nend;

  copy(nend=find_if(bgn,end,bind1st(not_equal_to<char>(),v)), end, bgn); // 去前空格
 
  RIter rbgn(bgn+(end-nend)-1),                // 利用反转迭代器
         rend=reverse_iterator<char*,char>(bgn);

  find_if(rbgn,rend,bind1st(not_equal_to<char>(),v))[-1]='\0'; // 去后空格
  return bgn;
}
}
 
 
int main(void)
{
 using namespace hpho;
 std::string s="   abc  sss    ";
 trim(s.begin(),s.end(),' ');
 printf("[%s]",s.c_str());
 return 0;
}

输出所有正整数N拆解和

输出所有正整数N拆解和是指
若N=2则输出1+1
若N=3则输出1+2,1+1+1
若N=4则输出1+3,2+2,1+1+2,1+1+1+1
.....
----------------------------------------------------
 
#include <stdio.h>
unsigned long total;
 
void foo(int* d, int n, int j, int s){
  int i;
 
  if(s==n){
    ++total;
    for(i=0;i<j-1;++i)
      printf("%d+",d[i]);
    printf("%d\n",d[i]);
    return;
  }
 
  for(i=1;i<=n-1;++i){
    d[j]=i;
    if((j>0&&d[j-1]>d[j])||s+i>n)
      continue;
    foo(d,n,j+1,s+i);
  }
}
 
int main(){
  int d[100]={0};
  int N=10;
  foo(d,N,0,0);
  return 0;
}
 
///////////////////////////////////////
因为N最少拆分为N个1相加所以可以假设有dn (n=0...N;dn=0...9)位数相加.
只要
for(i1=0;i1<=9;++i1)
   for(i2=0;i2<=9;++i2)     
      for(i3=0;i3<=9;++i3) 
         for(....)
             if(d[i1]+d[i2]+....+d[in]==N){
                  printf(...);
              }
穷举每个位就能过滤出符合条件的解。然而1+1+2和2+1+1和1+2+1是一样的。
这时规定一个序(上面程序是升序:1+1+2)那么就能唯一确定,这里程序所对应的条件为(j>0&&d[j-1]<d[j])。
而另一个过滤条件(边界条件)是d[i1]+d[i2]+....+d[ij]<N的话则继续下一位搜索。这里程序所对应的是s这个值只有当s<=N时才相下一位搜索。
虽然算法是正确的,但原题是要的是1000的所有拆解,但这个数实在太大。按以上算法是不可能完成!

初等行变换求逆矩阵

这是用初等行变换做的矩阵求逆
// 某行乘一个数
void f(double* v, int n, double d){
  int j;
  for(j=0;j<n;++j){
    v[j]*=d;
  }
}
 
// 某行乘一个数后加的另一行
void g(double* v1, double* v2, int n, double d){
  int j;
  double t;
  for(j=0;j<n;++j){
    t=v1[j]*d;
    v2[j]+=t;
  }
}
 
// 利用f()和g()两个变换求逆矩
void inverseM(double* m1, double* m2,int n){
   int i,j;
   double d;
   
   for(i=0;i<n;++i){
      d=1.0/m1[n*i+i];
     f(m1+n*i,n,d);f(m2+n*i,n,d);
     for(j=0;j<n;++j){
       if(i!=j){
          d=-m1[n*j+i];
          g(m1+n*i,m1+n*j,n,d);g(m2+n*i,m2+n*j,n,d);
     }
   }
 }
}

void printM(double* m, int n){
 int i,j;
 for(i=0;i<n;++i){
  for(j=0;j<n;++j){
   printf("%f ", m[n*i+j]);
  }
  printf("\n");
 }
}
 
int main(){
double m[9]={5.3,4.2,8.5,9.4,6.8,5.8,3.7,7.6,1.8};
double m1[9]={1,0,0,0,1,0,0,0,1};
inverseM(m,m1,3);
printM(m1,3);
}
 

ieee754标准 32位浮点数分析程序(未完)

// 用来研究二进制浮点用的,还有64位的以后补上
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double darr[]={
0.50000000000000000000000,
0.25000000000000000000000,
0.12500000000000000000000,
0.06250000000000000000000,
0.03125000000000000000000,
0.01562500000000000000000,
0.00781250000000000000000,
0.00390625000000000000000,
0.00195312500000000000000,
0.00097656250000000000000,
0.00048828125000000000000,
0.00024414062500000000000,
0.00012207031250000000000,
0.00006103515625000000000,
0.00003051757812500000000,
0.00001525878906250000000,
0.00000762939453125000000,
0.00000381469726562500000,
0.00000190734863281250000,
0.00000095367431640625000,
0.00000047683715820312500,
0.00000023841857910156250,
0.00000011920928955078125,
};
unsigned char buf[128]={0};
float val=0.0;
unsigned long* pl;
unsigned s;
unsigned int E,M;
int e;
double m=1.0;
char ss;
 
void ieee754_32(float val)
{
 unsigned long i,j;
 pl=(unsigned long*)&val;
 s=((*pl)&0x80000000)>>31;
 ss=(s?'-':'+');
 E=((*pl)&0x7F800000)>>23; 
 M=((*pl)&0x7FFFFF);
 /*
 if(E==0xff)
 {
  if(M==0)
  {
   printf("%s\n",(s?"-infinite":"+infinite"));
  }
  else
  {
   printf("NaN(Not a Number)\n");
   return;
  }
 }
 else
 {
 */
  printf("val: %f\t%x\n", val, *pl);
 //}
 printf("s: %d\t%c\n", s, ss);
 printf("E: %d\n", E);
 printf("M: %x\n", M);
 for(j=0,i=0x400000; i>0; i>>=1,++j)
 {
  if(M&i)
  {
   m+=darr[j];
  }
 }
 if(E>0)
 {
  e=E-127;
  printf("e=|E|-127: %d\n", e);
  printf("m=M+1: %0.23f\n\n", m);
 }
 else
 {
  printf("e=1-127: %d\n", e);
  printf("m=M: %0.23f\n\n", m);
 }
 
 printf("format: 1^s * m * 2^e\n");
 printf("%c%0.23f*%f = %0.23f\n", ss,m,pow(2,e),m*pow(2,e));
}

int main(int argc,char *argv[]){
 if(argc>=2)
    val=(float)atof(argv[1]);
 else
    scanf("%f", &val);
 ieee754_32(val);
 system("pause");
 return 0;
}

把有中文英文混合的串分解为固定长度的子串

#include <ctype.h>
 
int truncation(char const* src, int slen, int idx, char* line, int len){
  int j=idx+len, k=0;
  while(idx<slen&&idx<j) {
    *line=src[idx];
    if(isprint((unsigned char)*line))
      ++k;
 ++idx;
 ++line;
  }
  if(idx>=slen) {
    *line='\0';
    return idx;
  }
  else if((len-k)>0&&(len-k)%2) {
    *(line-1)='\0';--idx;
  }
  *line='\0';
    return idx;
}
 
int main(){
  char text[]="一切从实际出发1,二氧化碳, abc三番五次123def";
  char buf[7];
  int i=0,l=strlen(text);
  while(i<l)
  {
    i=truncation(text,l,i,buf,sizeof(buf)-1);
    printf("%s\n",buf);
  }
  return 0;
}
 
/////////////////////////////////////////////////
1,必须注意char是有符号的.
2,使用isXXX函数时务必加强转型为unsigned char,理由是1.
3,若函数是需要加工串(如:统计,截断,...)时一般最好还是使用内建的类型指针.
 上述函数参数若用string或CString的话就必须先复制再统计,或时一边统计一边调用operator[]()或at()还处理每一个字符.这样增加了处理成本!

题目

一、题目:
这个题目比较变态 [所有相关帖子]

只用以下的符号:
~, !, ^,&, +, |, <<, >>.
实现 x?y:z
 
二、偶的答案:
y & ~x + x + !x | z & ~x + x + !!x;
三、分析:
整个式子由三部分构成:
1, ~x + x
2, !x 和 !!x
3, y & (1 + 2)
1,
无论x是什么数
~x + x 等同 ~x | x 等同 0xffffffff
2,
!x和!!x结果只会是0或1, 因为!操作符返回的是一个bool(true, false)
3, 1+2的意思
(~x + x + !x)和(~x + x + !!x)
意思就是:
0xffffffff + 0 或 0xffffffff + 1
而0xffffffff + 1等于0
4, 最终是要x!=0时产生0和0xffffffff, x==0时产生0xffffffff和0
这就做到(y & 0 | z & 0xffffffff) 或 (y & 0xffffffff | z & 0) 的效果.
 (y&0) 和 (z&0) 结是0
(y & 0xffffffff)和(z & 0xffffffff)都会自己y和z.
因为题目没给用"()"的原因所以要特别注意运算符级别因此没选用(~x | x)而是用(~x + x).
    看完这个后或许大家会有更好的答案, 期待中......!  :-)
注: 这里假定x,y,z为整形
posted on 2005-12-13 15:06 metaprogram的BLOG
 
Updated 7/13/2008
Updated 7/7/2008