Write a function that given a string of digits and a target value, prints where to put +'s and *'s between the digits so they combine exactly to the target value. Note there may be more than one answer, it doesn't matter which one you print.
Examples:
"1231231234",11353 -> "12*3+1+23*123*4"
"3456237490",1185 -> "3*4*56+2+3*7+490"

"3456237490",9191 -> "no solution"

方案一:(不是俺想出)可供参考(用了穷举法)

Code

posted @ 2009-04-28 13:38 yangbinhe 阅读(182) 评论(1) 编辑

一个字符串逆转,记录一下,主要是用到移位,没有用临时变量,面试中很可能考到。

int main()
{
char p[]  = "123456789";

int len = strlen(p) ;
int j = len-1;
for(int i=0;i<j;i++,j--)
p[i]
^=p[j]^=p[i]^=p[j];
cout
<<p;
system(
"pause");
    
return 0;
}

 

posted @ 2009-04-25 19:56 yangbinhe 阅读(182) 评论(0) 编辑

.NET中反射机制的使用与分析

[日期:2008-06-30] 来源:  作者:志伟
.NET中反射机制的使用与分析
.NET反射的定义:审查元数据并收集关于它的类型信息的能力。
元数据是一种二进制信息,用以对存储在公共语言运行库可移植可执行文件 (PE) 文件或存储在内存中的程序进行描述。将您的代码编译为 PE 文件时,便会将元数据插入到该文件的一部分中。
而将代码转换为 Microsoft 中间语言 (MSIL) 并将其插入到该文件的另一部分中。在模块或程序集中定义和引用的每个类型和成员都将在元数据中进行说明。
当执行代码时,运行库将元数据加载到内存中,并引用它来发现有关代码的类、成员、继承等信息。

元数据以非特定语言的方式描述在代码中定义的每一类型和成员。元数据存储以下信息: 

 程序集的说明:
 
1.    标识(名称、版本、区域性、公钥)。
2.    导出的类型。
3.    该程序集所依赖的其他程序集。
4.    运行所需的安全权限。
 类型的说明:
1.    名称、可见性、基类和实现的接口。
2.    成员(方法、字段、属性、事件、嵌套的类型)。
 
 属性:
 
1.    修饰类型和成员的其他说明性元素。  
 
 System.reflection命名空间包含的几个类,允许你反射(解析)这些元数据表的代码和反射相关的命名空间(我们就是通过这几个命名空间访问反射信息):
 
System.Reflection.MemberInfo
System.Reflection.EventInfo
System.Reflection.FieldInfo
System.Reflection.MethodBase
System.Reflection.ConstructorInfo
System.Reflection.MethodInfo
System.Reflection.PropertyInfo
System.Type System.Reflection.Assembly

 

 

.NET反射的作用:
 
1. 可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现 有对象中获取类型。
 
2. 应用程序需要在运行时从某个特定的程序集中载入一个特定的类型,以便实现某个任务时可以用到反射。
3. 反射主要应用与类库,这些类库需要知道一个类型的定义,以便提供更多的功能。
 
应用要点:
 
1.在.net实现工厂模式的时候好多都会用到反射。而工厂模式用的很多。
 
2. 使用反射动态绑定需要牺牲性能。
 
3. 有些元数据信息是不能通过反射获取的。
 
4. 某些反射类型是专门为那些clr 开发编译器的开发使用的,所以你要意识到不是所有的反射类型都是适合每个人的。  
 
反射单个程序集
 
1.    Load 方法:极力推荐的一种方法,Load 方法带有一个程序集标志并载入它,Load 将引起CLR把策略应用到程序集上。
 
先后在全局程序集缓冲区,应用程序基目录和私有路径下面查找该程序集,如果找不到该程序集系统抛出异常。
 
2. LoadFrom 方法:传递一个程序集文件的路径名(包括扩展名),CLR会载入您指定的这个程序集,传递的这个参数不能包含任何关于版本号的信息,区域性,和公钥信息,如果在指定路径找不到程序集抛出异常。
 
3. LoadWithPartialName:永远不要使用这个方法,因为应用程序不能确定再在载入的程序集的版本。该方法的唯一用途是帮助那些在.Net框架的测试环节使用.net 框架提供的某种行为的客户,这个方法将最终被抛弃不用。    
反射的层次模型

 

.NET反射的概述:

应用程序结构分为应用程序域—程序集—模块—类型—成员几个层次,公共语言运行库加载器管理应用程序域。

这些域在拥有相同应用程序范围的对象周围形成了确定边界。

这种管理包括将每个程序集加载到相应的应用程序域以及控制每个程序集中类型层次结构的内存布局。

 程序集包含模块,而模块包含类型,类型又包含成员,反射则提供了封装程序集、模块和类型的对象。

我们可以使用反射动态地创建类型的实例,将类型绑定到现有对象或从现有对象中获取类型,然后调用类型的方法或访问其字段和属性。反射通常具有以下用途:

 (1)使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例。
 
 (2)使用Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。
 
(3)使用ConstructorInfo了解构造函数的名称、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。
使用Type的GetConstructors或GetConstructor方法来调用特定的构造函数。
 
 (4)使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。
使用Type的GetMethods或GetMethod方法来调用特定的方法。
 
(5)使用FiedInfo了解字段的名称、访问修饰符(如public或private)和实现详细信息(如static)等,并获取或设置字段值。
 
(6)使用EventInfo了解事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等,添加或移除事件处理程序。
 
(7)使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,获取或设置属性值。
 
 (8)使用ParameterInfo了解参数的名称、数据类型、是输入参数还是输出参数,以及参数在方法签名中的位置等。

System.Reflection.Emit命名空间的类提供了一种特殊形式的反射,可以在运行时构造类型。

反射也可用于创建称为类型浏览器的应用程序,使用户能够选择类型,然后查看有关选定类型的信息。

此外,Jscript等语言编译器使用反射来构造符号表。System.Runtime.Serialization命名空间中的类使用反射来访问数据并确定要永久保存的字段,System.Runtime.Remoting命名空间中的类通过序列化来间接地使用反射。

反射的性能:

使用反射来调用类型或者触发方法,或者访问一个字段或者属性时clr 需 要做更多的工作:校验参数,检查权限等等,所以速度是非常慢的。

所以尽量不要使用反射进行编程,对于打算编写一个动态构造类型(晚绑定)的应用程序,可以采取以下的几种方式进行代替:

1、通过类的继承关系。让该类型从一个编译时可知的基础类型派生出来,在运行时生成该类 型的一个实例,将对其的引用放到其基础类型的一个变量中,然后调用该基础类型的虚方法。
 
2、通过接口实现。在运行时,构建该类型的一个实例,将对其的引用放到其接口类型的一个变量中,然后调用该接口定义的虚方法。
 
3、通过委托实现。让该类型实现一个方法,其名称和原型都与一个在编译时就已知的委托相符。
在运行时先构造该类型的实例,然后在用该方法的对象及名称构造出该委托的实例,接着通过委托调用你想要的方法。这个方法相对与前面两个方法所作的工作要多一些,效率更低一些。  

提高反射的性能:反射的性能损失主要来源于比较类型、遍历成员、调用成员三种情形,其中比较类型耗时最小。

调用成员耗时最多,所以尽量减少采用成员动态调用等反射方式可以提高应用程序性能。除此之外,采取后期绑定、避免将反射方法放到循环内产生放大效应等办法均可提升反射性能。

 示例如下:这是一个Calculator.dll

下面是通过反射检查和调用Calculator.dll中的的方法:

下面是运行出来的效果:

来源:http://www.zhiweinet.com/jiaocheng/2008-06/875.htm


posted @ 2009-04-17 14:13 yangbinhe 阅读(5628) 评论(2) 编辑
今天同学笔试,碰到了一个问题:从100个数中选出任意10个数,打印出所有可能。
这是排列,组合的问题,上网查了一下,挺多这方面的资料的,这是介绍一个组合算法:
假设从0-----5中选出3个数,那么可定义一个数组,数组下标为数据值,数组存储0,1,1表示选中,0表示未选中:
1  1  1  0  0
1  1  0  1  0
1  0  1  1  0
0  1  1  1  0
1  1  0  0  1
1  0  1  0  1
0  1  1  0  1
1  0  0  1  1
0  1  0  1  1
0  0  1  1  1
根据这个算法,自己写了一个程序(但是不知道到底为什么这样,如果有谁知道,请指教):
#include <stdio.h> 
#include 
<stdlib.h> 
int * NUM;        //指向实际的数值 
char * NUMFLAG;   //指向标志位 
static int number;  //存储总个数 
int sum=0;        //记录有多少次 
#define MAXNUM 5 
#define NUM(i) (*(NUM+(i)))           //第i个所存储的值 
#define NUMFLAG(i)  (*(NUMFLAG+(i)))  //表示第i个是否被选中,保存的为0,1 
#define swap(x,y)   do {(x)=(x)^(y);(y)=(x)^(y);(x)=(x)^(y);}while(0); 
void set(int num,int Allnum)   //设置小于num的为1,大于的为0 

  
int i; 
      
for(i=0;i<Allnum;i++
  { 
        
if(i<num) 
      NUMFLAG(i)
='1'
    
else 
      NUMFLAG(i)
='0';     
  } 

int  init() 

  
int i; 
  printf(
"there are %d number,please input the number you want to take out:\n",MAXNUM); 
  scanf(
"%d",&number); 
  
if(number>MAXNUM) 
  { 
    printf(
"sorry,the number is too big!\n"); 
        
return 1;           
  } 
  NUM
=(int *)(malloc(sizeof(int)*MAXNUM)); 
  NUMFLAG
=(char *)(malloc(sizeof(char)*MAXNUM)); 
  
set(number,MAXNUM); 
  
for(i=0;i<MAXNUM;i++
  { 
    NUM(i)
=i; 
  } 
  
return 0

void print()       

  
int i=0
  sum
++
  
while(i<MAXNUM) 
  { 
      
if(NUMFLAG(i)=='1'
        printf(
"%d ",NUM(i)); 
    i
++
  } 
  printf(
"\n"); 

void assemble() 

  
int j=0,k=0,number_0=0,number_1=0
  print(); 
  
do
     
if(NUMFLAG(k)=='1'&&NUMFLAG(k+1)=='0'
        { 
            swap(NUMFLAG(k),NUMFLAG(k
+1));    //交换1,0 
            set(number_1,k);                 //将所有1移到最左 
      print(); 
            number_1
=0;     
        number_0
=0
        k
=0
     }
else{                       //并不是连续的1,0 
        if(NUMFLAG(k)=='1')       
        number_1
++;         //记录之前1的个数 
      else number_0++;          //记录0的个数 
      k++
     } 
  }
while((k+1)<MAXNUM); 

int main() 

  init(); 
  assemble(); 
  printf(
"there are %d\n",sum); 
posted @ 2009-04-10 19:48 yangbinhe 阅读(95) 评论(0) 编辑

1、有一个整形数组,其元素包含正整数和负整数,找到它的所有子集中元素之和最大的那个子集。
如:[12,-3,54,-42,4,5,7],结果为63[12,-3,54]。
要求复杂度为O(n)。

int func(int n, int a[])
{
  
int sum = 0, b = 0, i;

  
for (i = 1; i <= n; i++)
  {
    
if (b>0) b+=a[i];
    
else b=a[i];
    
if (b>sum) sum = b;
  }
  
return sum;

 

2、求乱序排序的N个数中连续K个数的和的最大值。

具体思路:

假设有N:a1 a2 a3 a4 a5 ... aN

需要求出所有连续K的和,那么,先求出a1~ak的和sum

a(2)~a(k+1)的和=sum - a1 + a(k+1)---------------------(1)

a(3)~a(k+2)的和=(1)式结果-a(2) + a(k+2)

Code

 

posted @ 2009-04-10 17:22 yangbinhe 阅读(255) 评论(0) 编辑

checked和unchecked操作符用于整型算术运算时控制当前环境中的溢出检查。下列运算参与了checked和unchecked检查(操作数均为整数):

1)  预定义的++和―― 一元运算符。

2)  预定义的-一元运算符。

3)  预定义的+、-、×、/等二元操作符。

4)  从一种整型到另一种整型的显示数据转换。

 

(一)使用checked

若运算是常量表达式,则产生编译错误:The operation overflows at complie time in checked mode.

若运算是非常量表达式,则运行时会抛出一个溢出异常:OverFlowException异常。

checked 的用法可以是checked(//运算代码),也可以是checked{//运算代码},一般都是小量的代码。

先看下面代码:

            Byte b = 100;

            b 
+= 200;

            Console.WriteLine(b.ToString());

 结果并不是我们预想的输出300,输出是44。假设我们用于计算那是多么的危险,上述代码编译时编译器并没有告诉程序员运算溢出。而是偷偷的干了坏事...

下面我们加上checked,看效果如何:

            byte b = 200;
            
checked
            { 
                b 
+= 200;
            }
            Console.WriteLine( b.ToString());

可以看到程序并没有输出,而是在运行时抛出OverflowException,干了try catch的事情,告诉程序员说运算溢出了,赶快修bug。在运行时才抛出异常,在测试中带来些许麻烦,那么如何在程序编译时就抛出错误呢,事实上编译时是不能确定运算结果的,也就是说运算结果是在运行是才能确定,所以只有在运行时checked才做运算溢出检查。但是下列代码是编译不通过的(地球人都知道)

            byte b;
            
checked
            {
                b 
= 256;
            }
            Console.WriteLine( b.ToString());

输出错误 Constant value '300' cannot be converted to a 'byte' ,byte的范围是0~255嘛,编译当然报错。

需要指出的是,看下面代码:

Byte b = 100;
= (Byte)checked(b + 200);//不抛出System.OverflowException异常信息

这里解释一下,因为 b+ 200 的结果是int32,checked是对int32的检查当然没有运算溢出,但是再将结果转换成byte时没有checked,所以返回值会被截掉不符合目标类型的高位,输出不正确的结果。

 

(二)使用unchecked

无论运算是否是常量表达式,都没有编译错误或是运行时异常发生,只是返回值被截掉不符合目标类型的高位,用法类似checked。

参考资料:

[1]C#中的checked、unchecked操作符http://www.knowsky.com/301786.html

[2]基元类型和Checked、UnChecked操作符的使用 http://www.cnblogs.com/noviceliu/archive/2009/03/11/1408461.html

 

 

posted @ 2009-04-06 22:45 yangbinhe 阅读(239) 评论(0) 编辑