C++面试题

C/C++ 专栏收录该内容
22 篇文章 0 订阅

1.构造一个类MySingleton,使该类只能存在一个实例.
思路:
    将构造函数写为private的,然后通过一个成员静态函数来调用构造函数即可:)
例:
#include "iostream.h"
class MySingleton
{
private:
static MySingleton* _instance;
MySingleton(){ cout << "Construct MySingleton" << endl; } //构造函数私有
~MySingleton(){ cout << "Destroy MySingleton" << endl; } 
public:

static MySingleton& GetInstanceRef()
{
if (_instance == 0)
_instance = new MySingleton;
return *_instance;
}


static MySingleton* GetInstancePtr()
{
return &GetInstanceRef();
}


static ReleaseInstance()
{
if (_instance != 0)
{
delete _instance;
_instance=0;
}
}
};
MySingleton*  MySingleton::_instance=0;


int main(int argc, char* argv[])
{
MySingleton& my=MySingleton::GetInstanceRef();
MySingleton::ReleaseInstance();


return 0;
}






2.为什么两次结果不一样?
#include "stdio.h"


char* Test1()
{
char string[10];
char* str="0123456";
return string;
}
char* Test2()
{
char string[10];
char* str="0123456";
return str;
}
void main()
{
printf("%s\n",Test1());
printf("%s\n",Test2());
}




1.程序的输出是什么?(F)
#include "stdafx.h"
#include "stdio.h"


int main()
{
int i,sum;


for( i=1;i<=3;i++) sum+=i;
printf("%d",sum);


return 0;
}


sum没有初始化,所以结果是不可预知的。


补充:在VC debug中,如果int型变量未初始化,那么一般初始化为0xcccccccc。
而在release中,初始化的值又不一样。我们在使用变量时不应该依赖编译器的
初始化,而应该自己显式初始化。


扩展:
局部变量在栈,值不确定(前面几个说得不对,这和编译器无关,因为声明局部变量的时候就算是赋初值编译后也要加上一条赋值语句,就是说 int i=0; 等于 int i; i=0;两条语句!!没有哪个编译器会这么傻给局部变量也给默认值...)


全局和static在静态区.也就是程序的数据段里面.因为这个数据段不像动态分配,无论如何都要写东西进去.所以默认自然就是0了,要是想来个随机值编译器还要挨个生成随机数,多傻啊.这里赋了初值,就不需要再来一个赋值语句了.因为这个值就是写在程序二进制文件里面了.你如果定义全局变量int i=1; 打开二进制就能在i的地址上面找到写着1的值.


学会分析汇编代码:将每一个C语言代码进行反汇编


2.写构造函数和赋值运算符(T)
#include "iostream.h"
class Test
{
public:
int m_i;
public:
Test(); //默认构造函数.当Test t2;时调用
Test(int i); //Test t1(4);时调用
Test(const Test& t); //拷贝构造函数.当Test t2=t1;或Test t2(t1);时调用
Test& operator=(const Test&); //赋值运算符函数重载.t2=t1;时调用
};
Test::Test()
{
m_i=0;
}
Test::Test(int i)
{
m_i=i;
}
Test::Test(const Test& t)
{
m_i=t.m_i;
}
Test& Test::operator=(const Test& t)
{
m_i=t.m_i;
return *this;
}
void main()
{
Test t1(4);
Test t2;
t2=t1;
cout<<t2.m_i<<endl;
}


注意:
Test t2=t1;

Test t2;
t2=t1;
是不一样的。前者调用拷贝构造函数,后者先调用默认构造函数,然后调用赋值运算符函数。


3.虚函数(F)
多态性可以改善代码的组织性和可读性,同时也使创建的程序具有可扩展性。而虚函数是实现多态的重要方法。
而虚函数又是通过虚表和虚表指针实现的。


4.cast
(以后程序中转换都用这几个操作符,以示专业,哈哈)
There are several casting operators specific to the C++ language. These operators are intended to remove some of the ambiguity and danger inherent in old style C language casts. These operators are: 


dynamic_cast   Used for conversion of polymorphic types.
使用该操作符时,必须:
1.开启/GR编译选项,可以通过Project->Settings->C/C++->Category下的C/C++ Language(Enable ... RTTI)
2.被转换的指针必须是多态类,也就是带虚函数的类,被转换成的类和被转换类可以没有任何关系
3.不能将const转换为非const
所以dynamic_cast是最安全的转换,只有能够安全的转换时才能转换成功,转换时优先考虑dynamic_cast


static_cast   Used for conversion of nonpolymorphic types.
使用该操作符时,必须:
1.被转换成的类和被转换类必须是继承关系,否则编译都通不过
2.即使是多态类也可以转换,但没有安全性,不会转换失败,仅仅把指针的值赋过去而已
3.不能将const转换为非const


const_cast   Used to remove the const, volatile, and __unaligned attributes.
使用该操作符时,必须:
1.只能转换同一类型,去掉const,volatile, and __unaligned属性。


reinterpret_cast   Used for simple reinterpretation of bits. 
跟C中老的转换完全一样,不在迫不得已的情况下,不要用它。


Use const_cast and reinterpret_cast as a last resort, since these operators present the same dangers as old style casts. However, they are still necessary in order to completely replace old style casts.


例:
class B 

public:
virtual ~B();
};
B::~B()
{


}
class D : public B { /*...*/ };


void f(B* pb)
{
   D* pd1 = dynamic_cast<D*>(pb);  // pb必须是多态类,且将父类转换为子类是不安全的,所以转换失败,pd1 = NULL
   D* pd2 = static_cast<D*>(pb);   // 而static_cast不管这些,只管硬转
}


void main()
{

B* pb = new B();
f(pb);


system("pause");
}


5.写一个双向链表


6.关于成员变量初始化顺序
  根据成员变量在类中声明的先后顺序进行初始化。


7.纯虚函数,虚析构函数(理解得不清楚)
例:
#include "iostream.h"
class Base1
{
public:
~Base1(){cout<<"~Base1\n";}
};
class Derived1:public Base1
{
public:
~Derived1(){cout<<"~Derived1\n";}
};


class Base2{
public:
virtual ~Base2(){cout<<"~Base2\n";}
};
class Derived2:public Base2{
public:
~Derived2(){cout<<"~Derived2\n";}
};


void main(){
Base1* bp=new Derived1;
delete bp;
Base2* b2p=new Derived2;
delete b2p;
}


结果:
~Base1
~Derived2
~Base2


注:
当想通过基类指针操纵子类对象时,如果析构函数不是虚函数,那么在delete时子类的构造函数将不会被调用。
当基类的析构函数是虚的时,子类的析构函数会覆盖基类的析构函数,所以,delete时会调用基类的析构函数,而在子类析构函数最后,又会调用基类的析构函数,所以出现上面的结果。


8.写一个单链表


9.写个is-a和has-a(T)
组合常常被称为"has-a"(有)关系,比如"在小汽车中有发动机"
继承常常被称为"is-a"(是)关系, 比如"圆形是一种形体"


当我们在选择使用组合还是继承时就可以根据这两种模型判断。
你可以说小汽车是发动机吗?不能。所以我们选择组合
你可以说圆形里面有形体吗?不能。所以我们用继承
has-a:
class Engine{
public:
void start() const{}
void stop() const{}
};
class Wheel{
public:
void inflate(int psi) const{}
};
class Car{
public:
Engine engine;
Wheel  wheel[4];
};


void main()
{
Car car;
}


is-a:
class Pet{
public:
void eat() const{}
};
class Goldfish:public Pet{
public:
void swim() const{}
};


void main()
{
Goldfish goldfish;
}


10.struct vs. class.


   struct默认成员是public
   class默认默认成员是private
除此之外两者没有本质上的区别。
但一般习惯上我们在定义纯数据结构的时候用struct.否则用class.


11.STL里面vector的实现(内部空间的申请与分配)


12.怎样使一个class不能被实例化
   1.构造函数私有化2.抽象类


13.私有继承和public继承的区别
私有集成表示父类的所有共有函数在子类中都变成了私有函数,外部函数通过子类指针或对象不能访问父类的共有函数。
注意:私有继承并不是子类的成员函数也不能访问父类的共有函数,父类的所有保护或共有成员在子类的成员函数中都是可以访问的。
什么继承只能影响继承树外的访问!谨记!不要混淆了。
  


14.void *p的问题 
  不能使用++等指针算术(会出现error C2036: 'void *' : unknown size)


15.引用和指针的区别与联系
   引用类似于常量指针,一旦初始化,不能更改


16.简述一下hash算法


17.一个32位的数据,怎样找到最左边的一个1


18.一个4*4的格子,填入1~15 然后给个目标状态,怎样去搜索。


19.给你100万个数据,数据的值在0~65535之间 用最快的速度排序


20.最后一个问题:
   如果我们的一个软件产品,用户回复说:运行速度很慢,你怎么处理






21.n位的2进制数据怎样找最左边的1,如果是在最左位,这个数是负数,否则的话,左移
一位,看是否变成负数,这是O(n)的算法,O(n/2)的算法:二分方式查找


22.广度优先搜索+启发式


23.统计每个数字出现的频率


24.八皇后问题,详述解法 ---轻松搞定


25.kmp快速匹配算法 ---不算轻松的搞定


26.无向图中两点间最短路问题 ---伟大的迪杰克斯拉算法


27.空间中任意给两个向量,求角平分线 他给了个提示,解决


28.什么是平衡树 ---光说上概念来了,其他的不会了(昨晚光看b-,b+树了)


29.哈夫曼编码问题 ---回答的有些混乱


30.求1~10000的素数 ---筛选法,有点细节没处理好


31.有向图求环 ---我只会搜索,在他的提示下,还是没有做出来


32.给n个点,求凸包问题 ---hiahia,牛X一把,用二分作的!


33.堆排序 ---明确地告诉了他,俺忘了


34.四则运算


(1)给一个前缀表达式,然后求解 ---勉强做上来了


(2)给一个中缀表达式,求解 ---更勉强的作上来了


35.正则表达式 ---一开始不知道什么东西,后来他一解释,原来是正规式,刚考完,轻
松搞定




36.STL中container有哪些?


  答:vector,list,set,multiset,map,multimap,deque,bitset


2.map中的数据存储方式是什么?


  答:Hashtable


3.map和hashmap有什么区别?


  答:不知道。


4.hashmap是标准库中的吗?


  答:不是。


5.vector中的erase方法跟algorithm的remove有什么区别?


  答:我不怎么清楚,只知道remove_if可以用function object。还有可能vector自带的erase在执行过后会有一些优化的方法吧。


6.function object是什么?


  答:(这个我说了半天,反正就是描述一下)


2. 一般在什么时候构造函数被声明成private呢?


   答:比如要阻止编译器生成默认的copy constructor


3. 什么时候编译器会生成默认的copy constructor呢?


   答:只要自己没写,而程序中需要,都会生成


4. 如果你已经写了一个构造函数,编译器还会生成copy constructor吗?


   答:会


7. 为什么说如果一个类作为基类,则它的析构函数要声明成virtual的?


   答:(Effective C++ 条款14,我当时刚刚复习过,呵呵)


8. inline的函数和#define有什么区别?


   答:类型检查


9. inline是什么意思?


   答:就是不产生call,直接把函数的代码嵌入程序。但是inline不是强制的,是
编译器根据需要决定函数是否真的被inline


10. 那你说说什么时候会真的被inline,什么时候不会呢?


   答:(略)


11. 如果把一个类的成员函数写在类的声明中是什么意思?


   答:inline


12. public继承和private继承有什么架构上的区别?


   答:public是is-a的关系,private是has-a的关系


13. 在多继承的时候,如果一个类继承同时继承自class A和class B,而class A和
B中都有一个函数叫foo(),如何明确的在子类中指出override哪个父类的foo()?


   答:虚拟继承吧……(我想了半天也不记得这个怎么弄了,他也就没有继续难为
我)


14. 虚拟继承的语法是什么?


   答:class C : public A, virtual public B


15. 部分模版特例化(我忘了他当时怎么翻译这个词的了,反正就是partial temp
late specialization)和全部模版特例化有什么区别?


   答:(想了半天)就是是不是还有一个通用的模版的区别。这个特性在VC中不支
持,所以我不是很熟悉,不好意思……


16. 哦?VC不支持?你确定


   答:确定!(.net刚出的时候,我特意看过MSDN,上面写着VC7.0中有3个C++的
特性没有支持,其中就有这个,没想到他连这个都考!)




1.编一个函数,使一个单向链表转置


2.拆解一个整数,比如4,可以拆解成
 4=3+1
 4=2+2
 4=2+1+1
 4=1+1+1+1


4.不用库函数,实现strcpy或者memcpy等函数






1.已知strcpy 函数的原型是:
char *strcpy(char *strDest, const char *strSrc);
其中strDest 是目的字符串,strSrc 是源字符串。不调用C++/C 的字符串库函数,请编写函数strcpy
答案:
char *strcpy(char *strDest, const char *strSrc)
{
if ( strDest == NULL || strSrc == NULL)             //VC上的strcpy函数是没有这个检查的,如果传递NULL,程序直接出线访问非法内存
return NULL ;
if ( strDest == strSrc)
return strDest ;
char *tempptr = strDest ;
while( (*strDest++ = *strSrc++) != '\0')
;
return tempptr ;
}


2.已知类String 的原型为:
class String
{
public:
String(const char *str = NULL); // 普通构造函数
String(const String &other); // 拷贝构造函数
~ String(void); // 析构函数
String & operate =(const String &other); // 赋值函数
private:
char *m_data; // 用于保存字符串
};
请编写String 的上述4 个函数。
答案:
String::String(const char *str)
{
if ( str == NULL ) //strlen在参数为NULL时会抛异常才会有这步判断
{
m_data = new char[1] ;
m_data[0] = '' ;
}
else
{
m_data = new char[strlen(str) + 1];
strcpy(m_data,str);
}
}
String::String(const String &other)
{
m_data = new char[strlen(other.m_data) + 1];
strcpy(m_data,other.m_data);
}
String & String::operator =(const String &other)
{
if ( this == &other)
return *this ;
delete []m_data;
m_data = new char[strlen(other.m_data) + 1];
strcpy(m_data,other.m_data);
return *this ;
}
String::~ String(void)
{
delete []m_data ;
}


3.简答
1. 头文件中的ifndef/define/endif 是干什么用的?
答:防止该头文件被重复包含


2.#include <filename.h> 和#include “filename.h” 有什么区别?
答:对于#include <filename.h> ,编译器从标准库路径开始搜索filename.h
    对于#include "filename.h",编译器从用户的工作路径开始搜索filename.h


3. 在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern "C"?
答:C++语言支持函数重载,C 语言不支持函数重载。函数被C++编译后在库中的名字与C 语言的不同。假设某个函数的原型为: void foo(int x, int y);
该函数被C 编译器编译后在库中的名字为_foo , 而C++ 编译器则会产生像_foo_int_int 之类的名字。
C++提供了C 连接交换指定符号extern“C”来解决名字匹配问题。


4.一个类有基类、内部有一个其他类的成员对象,构造函数的执行顺序是怎样的?
答:先执行基类的(如果基类当中有虚基类,要先执行虚基类的,其他基类则按照声明派生类时的顺序依次执行),再执行成员对象的,最后执行自己的。


3.5 请描述一个你熟悉的设计模式(Autodesk)




6.在UML 中,聚合(aggregation)和组合(composition)有什么区别 (Autodesk)
答案:聚合关系更强,类似于pages 和book 的关系;组合关系要弱,类似于books和bookshelf 的关系。


7.C#和C++除了语法上的差别以外,有什么不同的地方?(Autodesk,Microsoft)
答案:(C#我只是了解,不是很精通)
(1) c#有垃圾自动回收机制,程序员不用担心对象的回收。(2)c#严禁使用指针,只能处理对象。如果希望使用指针,则仅可在unsafe 程序块中能使用指针。(3)c#只能单继承。(4)必须通过类名访问静态成员。不能像C++中那样,通过对象访问静态成员。(5)在子类中覆盖父类的虚函数时必须用关键字override,覆盖父类的方法要用关键字new


8.ADO.net 和ADO 的区别?
答案:实际上除了“能够让应用程序处理存储于DBMS 中的数据“这一基本相似点外,两者没有太多共同之处。但是ADO 使用OLE DB 接口并基于微软的COM 技术,而ADO.NET 拥有自己的ADO.NET 接口并且基于微软的.NET 体系架构。众所周知.NET 体系不同于COM 体系,ADO.NET 接口也就完全不同于ADO和OLE DB 接口,这也就是说ADO.NET 和ADO是两种数据访问方式。ADO.net 提供对XML 的支持。


9. new delete 与malloc free 的区别 ( Autodesk)
答案:用malloc 函数不能初始化对象,new 会调用对象的构造函数。delete 会调用对象的destructor,而free 不会调用对象的destructor.


10. #define DOUBLE(x) x+x (Autodesk)
i = 5*DOUBLE(10); i 是多少?正确的声明是什么?
答案:i 为60。正确的声明是#define DOUBLE(x) (x+x)


11. 有哪几种情况只能用intialization list 而不能用assignment? (Autodesk)
答案:当类中含有const、reference 成员变量;基类的构造函数都需要参数;类中含有其他类的成员对象,而该类的构造函数都需要参数。


12. C++是不是类型安全的? (Autodesk)
答案:不是。两个不同类型的指针之间可以强制转换。C#是类型安全的。


13. main 函数执行以前,还会执行什么代码? (Autodesk)
答案:全局对象的构造函数会在main 函数之前执行。


13. 描述内存分配方式以及它们的区别。 (Autodesk , Microsoft)
答案:
(1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。
(2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。
(3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。


14. 什么是虚拟存储器?virtual memory 怎样映射到physical memory?页面替换算法有哪些? (Microsoft)
见操作系统 p238 页。掌握的页面替换算法NRU,FIFO,第二次机会页面替换算法,LRU


15. 有四个同样的容器,里面装满了粒数相同的药丸,正常药丸的质量为m,变质药丸的质量为m+1,现在已知这四个容器中,有一个装的全是变质药丸,用电子秤只称一次,找出哪个容器装的是变质药丸 (Microsoft)
答案:把四个容器依次编号为1、2、3、4,然后从中分别取出1、2、3、4 粒药丸,称这10 粒药丸的质量,如果质量为10m+1,则说明第一个容器装的是变质药丸,如果为10m+2 则说明第二个装的变质药丸,依次类推。


16. 比较一下C++中static_cast 和 dynamic_cast 的区别。 (Autodesk)
答案:dynamic_casts在帮助你浏览继承层次上是有限制的。它不能被用于缺乏虚函数的类型上,它被用于安全地沿着类的继承关系向下进行类型转换。如你想在没有继承关系的类型中进行转换,你可能想到static_cast


17. 当一个类A 中没有生命任何成员变量与成员函数,这时sizeof(A)的值是多少,如果不是零,请解释一下编译器为什么没有让它为零。(Autodesk)
答案:肯定不是零。我举个反例,如果是零的话,声明一个class A[10]对象数组,而每一个对象占用的空间是零,这时就没办法区分A[0],A[1]…了


18. 在8086 汇编下,逻辑地址和物理地址是怎样转换的?(Intel)
答案:通用寄存器给出的地址,是段内偏移地址,相应段寄存器地址*10H+通用寄存器内地址,就得到了真正要访问的地址。


20. 描述一下C++的多态 (microsoft)
答案:C++的多态表现在两个部分,一个是静态连编下的函数重载,运算符重载;动态连编下的虚函数、纯虚函数(抽象类)


4.写出BOOL,int,float,指针类型的变量a 与零的比较语句。
答案:
BOOL : if ( !a )
int : if ( a == 0)
float : const EXPRESSION EXP = 0.000001
if ( a < EXP && a >-EXP)
pointer : if ( a != NULL)




5.请说出const 与#define 相比优点
答案:
(1) const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误。
(2) 有些集成化的调试工具可以对const 常量进行调试,但是不能对宏常量进行调试。




6.简述数组与指针的区别
数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。指针可以随时指向任意类型的内存块。
(1)修改内容上的差别
char a[] = “hello”;
a[0] = ‘X’;
char *p = “world”; // 注意p 指向常量字符串
p[0] = ‘X’; // 编译器不能发现该错误,运行时错误
(2) 用运算符sizeof 可以计算出数组的容量(字节数)。sizeof(p),p 为指针得到的是一个指针变量的字节数,而不是p 所指的内存容量。C++/C 语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。
char a[] = "hello world";
char *p = a;
cout<< sizeof(a) << endl; // 12 字节
cout<< sizeof(p) << endl; // 4 字节
计算数组和指针的内存容量
void Func(char a[100])
{
cout<< sizeof(a) << endl; // 4 字节而不是100 字节
}


7.类成员函数的重载、覆盖和隐藏区别
答案:
成员函数被重载的特征:
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
覆盖是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual 关键字。
“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)


8.There are two int variables: a and b, don’t use “if”, “? :”, “switch”
or other judgement statements, find out the biggest one of the two
numbers.
答案:( ( a + b ) + abs( a – b ) ) / 2


9.如何打印出当前源文件的文件名以及源文件的当前行号?
答案:
cout << __FILE__ ;
cout<<__LINE__ ;
__FILE__和__LINE__是系统预定义宏,这种宏并不是在某个文件中定义的,而是由编译器定义的。


10.main 主函数执行完毕后,是否可能会再执行一段代码,给出说明?
答案:可以,可以用_onexit 注册一个函数,它会在main 之后执行int fn1(void), fn2(void), fn3(void), fn4 (void);
void main( void )
{
String str("zhanglin");
_onexit( fn1 );
_onexit( fn2 );
_onexit( fn3 );
_onexit( fn4 );
printf( "This is executed first.\n" );
}
int fn1()
{
printf( "next.\n" );
return 0;
}
int fn2()
{
printf( "executed " );
return 0;
}
int fn3()
{
printf( "is " );
return 0;
}
int fn4()
{
printf( "This " );
return 0;
}
The _onexit function is passed the address of a function (func) to be called when the program terminates normally. Successive calls to _onexit create a register of functions that are executed in LIFO (last-in-first-out) order. The functions passed to _onexit cannot take parameters.


11.如何判断一段程序是由C 编译程序还是由C++编译程序编译的?
答案:
#ifdef __cplusplus
cout<<"c++";
#else
cout<<"c";
#endif


12.文件中有一组整数,要求排序后输出到另一个文件中
答案:
void Order(vector<int> &data) //起泡排序
{
int count = data.size() ;
int tag = false ;
for ( int i = 0 ; i < count ; i++)
{
for ( int j = 0 ; j < count - i - 1 ; j++)
{
if ( data[j] > data[j+1])
{
tag = true ;
int temp = data[j] ;
data[j] = data[j+1] ;
data[j+1] = temp ;
}
}
if ( !tag )
break ;
}
}
void main( void )
{
vector<int>data;
ifstream in("c:\\data.txt");
if ( !in)
{
cout<<"file error!";
exit(1);
}
int temp;
while (!in.eof())
{
in>>temp;
data.push_back(temp);
}
in.close();
Order(data);
ofstream out("c:\\result.txt");
if ( !out)
{
cout<<"file error!";
exit(1);
}
for ( i = 0 ; i < data.size() ; i++)
out<<data[i]<<" ";
out.close();
}


13.排序方法比较 (intel)
排序方法 平均时间 最坏时间 辅助存储
直接插入排序
起泡排序
快速排序
简单选择排序
堆排序
归并排序
基数排序


14.一个链表的结点结构
struct Node
{
int data ;
Node *next ;
};
typedef struct Node Node ;
(1)已知链表的头结点head,写一个函数把这个链表逆序 ( Intel)
Node * ReverseList(Node *head) //链表逆序
{
if ( head == NULL || head->next == NULL )
return head;
Node *p1 = head ;
Node *p2 = p1->next ;
Node *p3 = p2->next ;
p1->next = NULL ;
while ( p3 != NULL )
{
p2->next = p1 ;
p1 = p2 ;
p2 = p3 ;
p3 = p3->next ;
}
p2->next = p1 ;
head = p2 ;
return head ;
}
(2)已知两个链表head1 和head2 各自有序,请把它们合并成一个链表依然有序。
Node * Merge(Node *head1 , Node *head2)
{
if ( head1 == NULL)
return head2 ;
if ( head2 == NULL)
return head1 ;
Node *head = NULL ;
Node *p1 = NULL;
Node *p2 = NULL;
if ( head1->data < head2->data )
{
head = head1 ;
p1 = head1->next;
p2 = head2 ;
}
else
{
head = head2 ;
p2 = head2->next ;
p1 = head1 ;
}
Node *pcurrent = head ;
while ( p1 != NULL && p2 != NULL)
{
if ( p1->data <= p2->data )
{
pcurrent->next = p1 ;
pcurrent = p1 ;
p1 = p1->next ;
}
else
{
pcurrent->next = p2 ;
pcurrent = p2 ;
p2 = p2->next ;
}
}
if ( p1 != NULL )
pcurrent->next = p1 ;
if ( p2 != NULL )
pcurrent->next = p2 ;
return head ;
}
(2)已知两个链表head1 和head2 各自有序,请把它们合并成一个链表依然有序,这次要求用递归方法进行。 ( Autodesk)
答案:
Node * MergeRecursive(Node *head1 , Node *head2)
{
if ( head1 == NULL )
return head2 ;
if ( head2 == NULL)
return head1 ;
Node *head = NULL ;
if ( head1->data < head2->data )
{
head = head1 ;
head->next = MergeRecursive(head1->next,head2);
}
else
{
head = head2 ;
head->next = MergeRecursive(head1,head2->next);
}
return head ;
}


15.不运行程序写出该程序的运行结果?(T)
答案:
#include "iostream.h"
class B
{
public:
B()
{
cout<<"default constructor"<<endl;
}
~B()
{
cout<<"destructed"<<endl;
}
B(int i):data(i)
{
cout<<"constructed by parameter " << data <<endl;
}
private:
int data;
};
B Play( B b)
{
return b ;
}
int main(int argc, char* argv[])
{
B temp = Play(5);
return 0;
}


运行结果:
constructed by parameter 5
destructed
destructed


注释:上面这个题主要涉及自动类型转换。
     见<<Thinking in C++>>中296页。在C和C++中,如果编译器看到一个表达式或函数使用了一个不适合的内部类型,他经常会执行一个自动类型转换,从现在的类型到所要求的类型。在C++中,可以通过定义自动类型转换函数来为用户定义类型达到相同效果。这些函数有两种类型:特殊类型的构造函数和重载的运算符。在上例中,Play需要一个B类型的参数,但是我们传入的实参类型是int,此时,编译器会查看是否有适当的自动类型转换函数将int转变为B.显然,通过构造函数B(int i)可以实现。当Play返回之后,产生了一个临时B对象,然后编译器调用拷贝构造函数用临时对象初始化temp.因为我们没有定义拷贝构造函数,所以编译器默认产生一个拷贝构造函数,它的功能仅仅是进行位拷贝而已。这一条语句执行完,临时对象被销毁,调用析构函数。当出了main函数后,temp调用析构函数。:)


16.写一个函数,找出一个整数数组中,第二大的数(microsoft)(T)
   注意:类似于1   4    4    4这样的序列将认为1是第二大数


答案:(这是别人的答案,我使了一下,有点错,像上面的那种序列会找出结果为4,而不是1)
const int MINNUMBER = -32767 ;
int find_sec_max( int data[] , int count) //
{
int maxnumber = data[0] ;
int sec_max = MINNUMBER ;
for ( int i = 1 ; i < count ; i++)
{
if ( data[i] > maxnumber )
{
sec_max = maxnumber ;
maxnumber = data[i] ;
}
else
{
if ( data[i] > sec_max )//没考虑到data[i]等于maxnumber但data[i]大于sec_max 这种情况,应该什么都不做
sec_max = data[i] ;
}
}
return sec_max ;
}
(这是我的答案):
const int MINNUMBER=0x10000000;
bool find_sec_max(int data[],int count,int* result)
{
int maxnumber;int sec_num;
maxnumber=data[0];
sec_num=MINNUMBER;


for(int i=1;i<count;i++)
{
if(data[i]>maxnumber)
{
sec_num=maxnumber;
maxnumber=data[i];
continue;
}
if(data[i]<maxnumber)
{
if(data[i]>sec_num)
sec_num=data[i];
}

}
if(sec_num==MINNUMBER)
return false;
*result=sec_num;
return true;
}


17.写一个在一个字符串中寻找一个子串第一个位置的函数(T)
这个题目的一般算法比较简单我就不给出了,如果要求高效率的话请参见数据结构中的KMP 算法,不过在笔试时间有限情况下,写出那个算法还是挺难的。


布鲁特-福斯算法(简单,低效率):
bool find(char* source,char* desc,int* pos)//pos用来接收匹配时主串的数组下标
{
for(int i=0;i<strlen(source);i++)
{
for(int j=0;j<strlen(desc);j++)
{
if(source[i+j]!=desc[j])
break;
if(j==strlen(desc)-1)
{
*pos=i;
return true;
}
}
}
return false;
}
KMP算法(复杂,高效率):








1.用c实现两个128位正整数的最小公倍数
主要考虑大数类
1.#include "stdio.h"




int iszero(unsigned char a[],int n)
{
int i;
for(i=0;i<n;i++)
if(a[i]!='0') return 0;
return 1;
}


void init(unsigned char a[],int n,unsigned char c)
{
int i;
for(i=0;i<n;i++)
a[i]=c;


}


void copy(unsigned char a[],unsigned char b[],int n)
{
int i;
for(i=0;i<n;i++)
b[i]=a[i];
}


int len(unsigned char a[],int an)
{
for(int i=0;i<an;i++)
if(a[i]==0)
return i;


}
void standard(unsigned char a[],int an)
{
int la,i;
la=len(a,an);
if(la<an)
{
for(i=0;i<la;i++)
{
a[an-i]=a[la-i];
}
for(i=la;i<an;i++)
{
a[an-i]='0';
}
}


}






int greater(unsigned char a[],int an,unsigned char b[],int bn)
{
int i,la,lb;
la=len(a,an);
lb=len(b,bn);
if(la>lb) return 1;
if(la<lb) return -1;
for(i=0;i<la;i++)
{
if(a[an-la+i]>b[an-la+i]) return 1;
if(a[an-la+i]<b[an-la+i]) return -1;
}
return 0;




}


void minus(unsigned char a[],int an,unsigned char b[],int bn,unsigned char c[],int cn)
{
int i,la,lb,carry=0;
la=len(a,an);
lb=len(b,bn);
if(greater(a,an,b,bn)<0) return;
init(c,cn,'0');
for(i=0;i<la;i++)
{
c[an-1-i]=a[an-1-i]-b[an-1-i]-carry+'0';
carry=0;
if (c[an-1-i]<'0')
{ c[an-1-i]+=10;carry=1;}


}
}


void mod(unsigned char a[],int an,unsigned char b[],int bn,unsigned char c[],int cn)
{
init(c,cn,'0');
while(greater(a,an,b,bn)>=0)
{
minus(a,an,b,bn,c,cn);
copy(c,a,cn);


}
}




void main()
{
unsigned char a[128],b[128],c[128],d[128],e[128];
int i;
init(a,128,NULL);
init(b,128,NULL);
init(c,128,NULL);
init(d,128,NULL);
printf("input a:\n");


scanf("%c",&a[i]);
printf("input b:\n");
scanf("%c",&b[i]);


standard(a,128);
standard(b,128);


if(greater(a,128,b,128)<0)
{
copy(a,c,128);
copy(b,a,128);
copy(c,b,128);
}
copy(a,c,128);
copy(b,d,128);
init(e,128,'0');
mod(c,128,d,128,e,128);
while(iszero(e,128)==0)
{
copy(d,c,128);
copy(e,d,128);
init(e,128,'0');
mod(c,128,d,128,e,128);
}
for(i=0;i<len(d,128);i++)
printf("%c",d[i]);
}
求的是最大公约数,用char a[128]放数据 


2.Windows中COM编程中如何判断两个interface的指针是同一个父COM对象


3.TCP/IP连接的唯一性如何确定
三次握手




6.线程的优缺点,编程中应该注意的问题
线程执行开销小,但不利于资源的管理和保护;而进程刚好相反。








 






面试时最经常被问到的问题(Frenquently asked interview questions)之C/C++篇 选择自 mxclxp 的 Blog  -  [ 找工作 ]
面试时最经常被问到的问题(Frenquently asked interview questions)之C/C++篇     选择自 mxclxp 的 Blog 


以下接连几篇文章来自于:http://www.acetheinterview.com,本人只是做了搜集整理工作。希望对大家有用。


C/C++ Questions & Answers (1’ ~ 21’)


 


1、What is polymorphism?


'Polymorphism' is an object oriented term. Polymorphism may be defined as the ability of related objects to respond to the same message with different, but appropriate actions. In other words, polymorphism means taking more than one form.
Polymorphism leads to two important aspects in Object Oriented terminology - Function Overloading and Function Overriding.
Overloading is the practice of supplying more than one definition for a given function name in the same scope. The compiler is left to pick the appropriate version of the function or operator based on the arguments with which it is called.
Overriding refers to the modifications made in the sub class to the inherited methods from the base class to change their behaviour.


 


2、What is operator overloading?


When an operator is overloaded, it takes on an additional meaning relative to a certain class. But it can still retain all of its old meanings.


Examples:


1) The operators >> and << may be used for I/O operations because in the <iostream> header, they are overloaded.


2) In a stack class it is possible to overload the + operattor so that it appends the contents of one stack to the contents of another. But the + operator still retains its original meaning relative to other types of data.


Also Polymorphism can be achieved in C++ through operator overloading


3、Declare a void pointer.


I think the answer is simply
void* p;


malloc is just the library function called to allocated some memory and of course a void pointer will be returned , but it is the declaration of a void pointer.


4、What are templates?


C++ Templates allow u to generate families of functions or classes that can operate on a variety of different data types, freeing you from the need to create a separate function or class for each type. Using templates, u have the convenience of writing a single generic function or class definition, which the compiler automatically translates into a specific version of the function or class, for each of the different data types that your program actually uses.


Many data structures and algorithms can be defined independently of the type of data they work with. You can increase the amount of shared code by separating data-dependent portions from data-independent portions, and templates were introduced to help you do that.


5、Type-define a function pointer which takes a int and float as parameter and returns a float *.


the pointer to function can be type defined as:
typedef float*(*pf)(int a, float b) tagPF;


 


6、What does the following C statement do?


while(*c++ = *d++); assuming c and d are pointers to characters.


String copy is performed indeed but be careful with the space allocated for the destination string.
Check this example:


char s1[10]="abcde";
char s2[3];


char* c,*d;
c=s2;
d=s1;
while(*c++ = *d++);
printf("%s - %s\n",s1,s2);


The code is string copy. But it does not add a null pointer to the end(*). There should also be a check for overlapping addresses(O).


7、How do you call a C module within a C++ module.


You should use extern "C" for functions, compiled by C compiler and called within a C++ class. You should do that to force the linker to resolve the function name (precisely, the mangling of the name) correctly.


 


8、What is the difference between run time binding and compile time binding? Discuss.


Compile Time Binding : In case of operator overloading and function overloading the name of the function is resolved during the compile time . Even if there are two or more functions with the same name the compiler mangles the name so that each function is uniquely identified . This has to be resolved at compile time and is known as compile-time binding or early binding.


Run Time Binding : In case of polymorphism (virtual functions) if a base class pointer(or reference) is allocated a pointer(or reference) of derived class the actual function called is determined only during runtime through the virtual table entry . This is runtime binding or late binding


9、Compare and contrast C++ and Java.


1>Platform Independent : Java code is said to be a multiplatform code and can run on any platform because after the compilation of the source code byte code(s) are created rather than a binary code so it can run on any platform which supports JVM concept but on the contrast at time(s) it slows down the application tremendously


2> Garbage Collection : Java handles freeing up of the memory but this is not guranteed since the GC thread has the lowest priority


3>Operator Overloading : is not provided in Java,but what are the advantages of Operator Overloading but one may question what are its advantages, well it makes a more readable and a modular code. In c++ cin and cout objects can also be overloaded which again leads to a better readability and flexibility


4> Multiple Inheritance : Java does provide multiple inheritance in form of Interfaces, In Java a class can not inherit from more than one class but it definitely can implement any number of interfaces


5> Templates: in c++ give such a lot of flexibility and avoids redundant coding which again is not provided by Java


10、Why does C/C++ give better run-time performance then Java?


That's because the Java bytecode is interpreted, not compiled. Programs
written in C are compiled into binaries which can be executed by a specific computer processor. Programs written in Java require one more step -- they must be interpreted by the Java "virtual machine" before running on a particular computer architecture. As a result, a computer running a Java program has to execute more machine-language instructions to do the same amount of work than a computer running an equivalent program written in C.


 


11、Does C++ come with in-built threading support.


No. C++ does not support in-built Multithreading. To do so, you must use the operating system functions manually. (Better use pthread library.)


 


12、Class A derived B derived C. All have foo(). I cast C to A and call foo(). What happens?(*)


--foo() for class C will be called.


--it depends. if in A foo is defined as virtual function. then call C's foo(), if it doesn't defined virtual, then call A's foo()


--Actually, if access is NOT specified, it deafults to private derivation. In private derivation, binding is static. So, whether foo is declared virtual or not it still defaults to static binding. So, A->foo() is called. However, If a public derivation is specified from C <-- B and B <-- A, then if foo() is virtual C->foo() is called; if foo() is non virtual A->foo() is called.


--But I think there is an important thing neglected by all of you, that is ‘cast C to A’, NOT ‘cast C* to A*’, So the correct answer is A.foo() will be called.


13、All classes A, B, C have default constructor, foo() that calls parent foo() and allocates 100 bytes to their own private local variable, and a destructor that frees the 100 bytes. I create a C object and then destroy it. What's the problem? Did all the memory get freed? What if I create C, cast to A, and then destroy it. How would I make sure memory is freed?


--destructor must be "virtual" and each destructor must call parent destructor


 


14、What errors are caught at compile time vs link time?


Syntactical and symantical errors (code errors) are caught at compile time.
Dependency errors (for example resolving function calls or errors in including other modules) are caught at link time.


15、What is the value of "a" after this?
int (*a) [10];
a++;


int (*a)[10]; represents the declaration of a pointer to an array of ten integers. So the value of a is initially some address allocated by the compiler and don't rely on the fact the address is 0 as it happens for static variables.
The value can be zero if you add the "static" keyword in front of declaration but I don't advise you to further use this pointer to access some elements.
If the integer is n bytes ( 2 or 4 depending on the language) it is true that the value of a will be increase with 10*n.


Test this program to understand:


#include <stdio.h>


void main(int argc,char*argv[])
{
int b[10]={1,2,3,4};
int (*a)[10];
printf("%p\n", a);       // invalid address!!
printf("%d\n",(*a)[0]);  // runtime error!!
a++;                     // advance 10 * sizeof(int) bytes
printf("%p\n", a);
a=&b;
printf("%p\n", a);
printf("%d\n",(*a)[0]);
}


16、What is wrong with this?
main(){
int *ptr;
*ptr=10;
}


Actual reality is like this. When the pointer is declared it contains some garbage value as u know. Conceptually speaking it points to location indicated by that "garbage memory address". Now when we assign some value to *a ; i.e.
*a=12;
we are trying to place 12 in the memory cell number indicated by 'a' ; which in this case is any random memory address because it is garbage. So the program will be compiled fine. But when run ; if the garbage value assigned to 'a' is invalid (or restricted by OS) memory address ; the OS will generate error. So its upto OS.


But technically program is fine.
-Dhiraj


17、Given int n, i=10, j=20, x=3, y = 100;
What is the value of n and y at the end of each of the following expressions?
a) n = (i > j) && (x < ++y);
b) n = (j - i) && (x < y++);
c) n = (i < j)


1> n = 0, y = 100, second condition will not be evaluated.


2> n = 1, y = 101


3> n = 1, y = 100


18、int x = 5;
int y = 7;
What is the value of x and y after the expression y+=x++;
Y = 12 and X = 6
Why? because X will be incremented after y = Y+X has been carried out and result has been assigned to Y.
if it would have been y+=++x then the value of y would have been equal to 13 and x = 6
I am sure about this
Mohit


19、What's the difference between C and C++?


C is Top Down Approach
C++ is Bottom Up Programming approach.


C does not support OOP (Object Oriented Programming) and do not support PolyMorphism, Inheritence, Encapsulation, Function OverLoading.


There is an important difference but often neglected by many people is the error handling.


Some common C style commands and there corresponding C++ style commands are shown below.




Console I/O
***********
C
===
printf("Hello World!\n");
scanf("%s", name);
C++
===
cout << "Hello World!" << endl;
cin >> name;


Comments
********
C
===
/* comment */
C++
===
// comment


File extensions
***************
C
===
.c, .h
C++
===
.C, .h, .CPP, .HPP


File I/O
*********
C
===
out = fopen("output_file.dat", "wb");
in = fopen("input_file.dat", "rb");
C++
===
ofstream out("output_file.dat");
ifstream in("input_file.dat");


Dynamic Memory
**************
C
===
text = (char *) malloc(1000);
free(text);
C++
===
text = new char[1000];
delete [] text;


Constants
*********
C
===
#define PI 3.14159
C++
===
const float PI = 3.14159;


Macros
******
C
===
#define MAX(a,b) ((a) > (b) ? (a) : (b))
C++
===
inline int MAX(int a, int b) { return a > b ? a : b; }




20、What does Public and Private mean in C++


--Public:
Makes class memebrs accessible outside the class. It can be accessed in the C code.
Private:
Makes the members specified accessible only to the class and it's functions.
--public / private have two different meanings in C++:
1. To specify the access privilege of the class members.
2. To specify what type of inheritance.


21、Is it possible to keep 2 stacks in a single array, if one grows from position one of the array, and the other grows from the last position. Write a procedure PUSH(x,s) that pushes element x onto stack S, where S is one or the other of these two stacks. Include all necessary error checks (Sent by Puneet Saraf)
The question did not ask for a suggestion. It is definitely possible to implement 2 stacks using a single array. The array shud be visible to both stacks (and therefore be global, or shud provide equivalent effect). Also the stack tops shud be taken care of. one top will decrement everytime the push method is called and one would be incremented. As soon as s1.top==s2.top we shud throw an exception.






面试常考问题


1、文档在开发中的作用及重要性;


2、数据结构问题:树、二叉树、链表、队列、堆栈;


3、数据库基本知识:B_Tree、R_Tree等;






5、怎样使程序易于维护;


6、指针和引用;


(1)int x = 20;


    Int* ptrx = &x; //声明指针,并赋值


    Int z = *ptrx;//重引用指针(dereferencing pointer)


注:ptrx——x的内存地址


    *ptrx——ptrx所指向的对象的值,即x的值


(2)引用(Reference)


MyStruct* pStruct = new MyStruct;


    MyStruct& Ref = *pStruct;


    Ref.x = 100;


等同于


MyStruct& Ref = * new MyStruct;


    Ref.x = 100;


(3)引用与指针的区别:


指针可以先声明再赋值;


而引用不可以,它必须在声明时就进行初始化。




用C++编程实现大数相乘的功能。编译工具不限,请在答卷中说明即可。答卷包括源代码和可执行文件。






1.A,B分别为500位以内的一个大数,请求出A*B的结果。


下面的内容可以用来验证你的功能


A= 2183924444444444448888888888888888888888500000000000000438888888888888333333333333333333333333333333333111111111111111111000000000004444444444444444475888888888888888888888888888888888888888888883499999999999999999999999999999999999999999992000000000000000000000




B= 38888888888899999999999999999999999999889999999999999999999999999999100000000000000000000000000036666666666666661711111111111111111111111111111111111111111111111111348999999999999999999999999998888888888899999999999999999999999999888888




A*B= 084930395061752661061728395061777777777522422632098761127690123456793012863061771166662666666618468966109876954310325589229851913558393813401259061729635920987666893089578354567901238378268246046746553283882310883951686248900617446672363367064666164327067654325713840070635796642855308566777190063032654321512917291554358024685185185209632790088518518570858122174339502222222222218728367117098765432038886985777777777777777778376548008888888888800000000000000000000000000888896000000000000000000000


***********************************************************************************




A= 218392444444444444044444444444444444758888888888888888888888888888888888888888888834999999999999999999999999999999999999999999920000008888888888888888888888500000000000000438888888888888333333333333333333333333333333333111111111111111111000000000004444444444444444475888888888888888888888888888888888888888888883499999999999999999999999999999999999999999992000000000000000000000




B= 3888888888889111111111111111111111111111111111111134899999999999999999999999999888888888889999999999999999999999999988889999999999999999999999999889999999999999999999999999999100000000000000000000000000036666666666666661711111111111111111111111111111111111111111111111111348999999999999999999999999998888888888899999999999999999999999999888888


A*B= 849303950617332480716049382715960495050000000000075071856804938271595422716049358240661801514251279012345678567901197203289571890122213845216790101408926381553092451407322634369444889174728395421728870318501187493790032617231707162296327851777431594889514539637277961784902110117269133818928788889019453983152957149517479011147523897533290301876458567845648319801409015506155920707870899113855038252567844183512690493833136047957481657679192421780617446915023580255777346144427654325713840070635796642855308566777190063032654321512917291554358024685185185209632790088518518570858122174339502222222222218728367117098765432038886985777777777777777778376548008888888888800000000000000000000000000888896000000000000000000000
[题目完]
#include <iostream>
#include <Cstring>


const int MSL = 500;
const int MRL = 1000;


using namespace std;


void Initial(char* A);
void ShiftLeft(char* A, int time);
void Add(char* A, char* B);
void Print(char* A);


int main ()
{
char A[MSL] = "21839244444444444488888888888888888888885"
"00000000000000438888888888888333333333333"
"33333333333333333333311111111111111111100"
"00000000044444444444444444758888888888888"
"88888888888888888888888888888883499999999"
"99999999999999999999999999999999999200000"
"0000000000000000";
//{'\0'};
char B[MSL] = "38888888888899999999999999999999999999889"
"99999999999999999999999999910000000000000"
"00000000000000366666666666666617111111111"
"11111111111111111111111111111111111111111"
"34899999999999999999999999999888888888889"
"9999999999999999999999999888888";
//{'\0'};
char C[MRL];
char D[MRL];
Initial(C);
Initial(D);


//cin>>A;
//cin>>B;


int fal = strlen(A);
int fbl = strlen(B);
int carry = 0;


for(int i = 0; i < fbl; i++)
{
carry = 0;
Initial(C);


for(int j = 0; j < fal; j++)
{
int k = MRL - j - 1;
int g = fal - j - 1;
int h = fbl - i - 1;
int facta = A[g] - 48;
int factb = B[h] - 48;
int result = facta * factb + carry;
C[k] = (char)((result % 10) + 48);
carry = result / 10;


}


C[MRL - j - 1] = (char)(carry + 48);
ShiftLeft(C, i);
Add(D, C);
}


Print(D);
return 0;


}


void Initial(char* A)
{
for(int i = 0; i < MRL; i++)
{
A[i] = '0';
}
return;
}


void ShiftLeft(char* A, int time)
{
for(int j = 0; j < time; j++)
{
for(int i = 0; i < MRL - 1; i++)
{
A[i] = A[i + 1];
}
A[MRL - 1] = '0';
}
return;
}


void Add(char* A, char* B)
{
int carry = 0;
int result = 0;
for(int i = MRL - 1; i >= 0; i--)
{
result = A[i] + B[i] + carry - 48*2;
A[i] = (char)((result % 10) + 48);
carry = result / 10;
}
return;
}


void Print(char* A)
{
bool flag = true;
for(int i = 0; i < MRL; i++)
{
if(A[i] == '0' && flag)
{
;
}
else
{
flag = false;
cout<<A[i];
}
}
cout<<endl;
return;
}




2.华为面试题:判断一个数组中的哪些数是回文?
答:
#include "stdio.h"
int test(int n)
{
int m=n;
int d=0;
while(m)
{
d=d*10+m%10;
m/=10;
}
return d==n;
}


void main()
{
int i;
static int a[]={57,157,1331,151,95};
for (i=0;i<5;i++)
printf("%5d:%s\n",a[i],test(a[i])?"YES":"NO");
}
思路:将被判断的数进行颠倒,然后和原数相比,相等则是回文;不等则不是.如何颠倒不好理解:).


3.
主  题: 面试题,子串匹配问题,求最佳算法
作  者: davysh (有望)
等  级:
信 誉 值: 95
所属论坛: C/C++ C++ 语言
问题点数: 50
回复次数: 41
发表时间: 2005-09-01 18:52:26


两个字符串,统计其中一个字符串在另一个字符串中出现的次数。
原题记不大清楚,去过西门子医疗器械面世的朋友请补充一下。
回复人:zhouhuahai(道号"虚无") ( 四级(中级)) 信誉:100 2005-09-01 19:16:00 得分:0
?




int subStr(char *str, char *sub)
{
int len1, len2;
len1 = strlen(str);
len2 = strlen(sub);
int count = 0;


for(int i = 0; i < len1; i++)
{
int k = 0;
if(str[i] == sub[0])
for(int j = i; (k< len2) && (str[j] == sub[k]); j++, k++);
if(k == len2)
count++;
}


return count;


}
Top
回复人:zhouhuahai(道号"虚无") ( 四级(中级)) 信誉:100 2005-09-01 19:29:00 得分:0
?
哦,没看清题意:求最佳算法


再去想想......
Top
回复人:xiaocai0001(萧筱雨) ( 五级(中级)) 信誉:100 2005-09-01 19:30:00 得分:0
?
楼上的效率还不如KMP的高呢~
Top
回复人:takbj(剑之吻) ( 二级(初级)) 信誉:100 2005-09-01 19:57:00 得分:0
?
int subStr(char *str, char *sub)
{
int len1 = strlen(str),
len2 = strlen(sub),
count = 0,
a = 0;


for(int i = 0; i < len1; i++)
{
if(a&&str[i]==sub[a]){
if(++a==len2){ count++;a=0;}
continue;
}
i -= a-1;
a=0;
if(str[i] == sub[0]) a=1;
}


return count;
}
Top
回复人:takbj(剑之吻) ( 二级(初级)) 信誉:100 2005-09-01 19:58:00 得分:0
?
代码是长了点
Top
回复人:xiaocai0001(萧筱雨) ( 五级(中级)) 信誉:100 2005-09-01 20:03:00 得分:0
?
实质上和上面那位的一样,程序思路还不如上面的那位清晰~~
Top
回复人:foochow(恰似你的温柔) ( 一星(中级)) 信誉:100 2005-09-01 20:04:00 得分:0
?
KMP,不知道有没有错...
aaaa
aa
这种情况算2次还是3次,如果算2次的话把下面的代码it=it+m+1 改成 it=it+m+s;


.......................
#include<iostream>
#include<string>
#include<iterator>
using namespace std;
const int max=100;
int f[max],m=0;
void fail(string&st)
{
int len=st.length();
f[0]=-1;
for(int j=1;j<len;++j)
{
int i=f[j-1];
while(st[j]!=st[i+1]&&i>=0)i=f[i];
if(st[j]==st[i+1])f[j]=i+1;
else f[j]=-1;
}
}
bool find(string&tent,string&path)
{
int t=0,p=0;
int lent=tent.size();
int lenp=path.size();
while(t<lent&&p<lenp)
{
if(tent[t]==path[p])
{
++t;
++p;
}
else if(p==0) ++t;
else p=f[p-1]+1;
}
if(p<lenp)return false;
else
{
m=t-lenp;
return true;
}
}
int main()
{
string tent,path;
cout<<"请输入主串:";
cin>>tent;
cout<<"请输入模式串:";
cin>>path;
fail(path);
string::iterator it=tent.begin();
int n=0,s=path.size();
while(1)
{
string ps(it,tent.end());
if(ps.size()<s)break;
if(!find(ps,path))break;
n++;
it=it+m+1;
}
cout<<"模式串在主串中出现了:"<<n<<"次"<<endl;
system("PAUSE");
return 0;
}
Top
回复人:newpublic(小yu) ( 一级(初级)) 信誉:100 2005-09-01 20:17:00 得分:0
?
我的想法:先用KMP算法找匹配的子串,找到以后,直接在此位置开始继续运用KMP找子串,以此类推,就可以找到子串出现的次数了。我认为这样是时间最短的。
Top
回复人:xiaocai0001(萧筱雨) ( 五级(中级)) 信誉:100 2005-09-01 20:25:00 得分:0
?
要求效率,KMP方法是比较好的,只需要对原串进行一次扫描.
Top
回复人:qhfu(崩溃) ( 一星(中级)) 信誉:105 2005-09-01 20:30:00 得分:0
?
KMP 应该是最好的算法吧?


下面一个 Rabin-Karp 算法,性能也不错。
//rabin-carp-algorithm
void RKM(string text,string pattern,vector<int> &Vpos,int r,int d)
{
size_t n = text.length();
size_t m = pattern.length();
int p = 0,t = 0;
long h = pow(d,m-1);
h = h%r;
for(size_t i = 0;i<m;i++)
{
p = (d*p + pattern[i] - 'a') % r;
t = (d*t + text[i] - 'a') % r;
}
for(size_t i = 0;i<n-m;i++)
{
if(p == t)
if(pattern == text.substr(i,m))
Vpos.push_back(i);
if(i< n-m)
{
t = (d*(t - (text[i] - 'a')*h) + text[i+m] - 'a')%r;
t = t<0? r+t:t;
}
}
}


int main()
{
vector<int> result;
string s1,s2;
cout<<"input s1 : ";
cin>>s1;
cout<<endl;
cout<<"input s2 : ";
cin>>s2;
RKM(s1,s2,result,29,26);
vector<int>::iterator it = result.begin();
while(it != result.end())
{
cout<<*it++<<" ";
}
system("pause");
}
Top
回复人:qhfu(崩溃) ( 一星(中级)) 信誉:105 2005-09-01 21:05:00 得分:0
?
还有一个算法, 用有穷自动机
//string matcher with finite automata
void SFA(string text,vector<vector<int> >& Pvec)
{
size_t n = text.length();
int m = Pvec.size();
int q = 0;
for(int i = 0;i<n;i++)
{
q = Pvec[q][text[i] - 'a'];
if (q == m-1)
cout<<"pattern occurs with shift"<<i-m+2<<std::endl;
}
}


//compute transition function
void CTF(string pattern,vector<vector<int> > & Pvec)
{


size_t m = pattern.length();
Pvec.resize(m+1);
for(int i = 0;i<m+1;i++)
Pvec[i].resize(26);


for(int q = 0;q<m+1;q++)
{
for(int a = 0;a<26;a++)
{
int k = m+1<q+2 ? m+1:q+2;
do
{
k = k - 1;
}while(( k > 0)&&(pattern.substr(0,k) != (pattern.substr(0,q).substr(q-k+1,k-1)+static_cast<char>('a'+a))));
Pvec[q][a] = k;
}
}
}
Top
回复人:lalalalala(van) ( 一级(初级)) 信誉:100 2005-09-01 21:17:00 得分:0
?
int subStr(char *str, char *sub)
{
int i, l;
int count;
char *s, *t;


l = strlen(str) - strlen(sub) + 1;
i = 0;
count = 0;
while(i>=l)
{
s = str+i;
t = sub;
while(s++==t++);
if(*t=='\0')count++;
i++;
}
}
Top
回复人:lovesnow1314(流浪) ( 一级(初级)) 信誉:100 2005-09-02 14:02:00 得分:0
?
mark
Top
回复人:bugebear3() ( 二级(初级)) 信誉:100 2005-09-02 14:06:00 得分:0
?
要实现不难,最佳的吗?..............
Top
回复人:heguosheng(何国胜) ( 一级(初级)) 信誉:100 2005-09-02 18:18:00 得分:0
?
mark
Top
回复人:dog0883(笨狗一条) ( 一级(初级)) 信誉:100 2005-09-02 18:49:00 得分:0
?
个人觉得应该用KMP扫描,主串某一位置匹配后从该位置的下一位置继续开始匹配
Top
回复人:ruodeer(一直在大连) ( 一级(初级)) 信誉:100 2005-09-02 22:30:00 得分:0
?
留个名,明天继续看,研究一下!
Top
回复人:snowbirdfly(胡晋) ( 三级(初级)) 信誉:100 2005-09-02 23:03:00 得分:0
?
我也觉得KMP实现起来效率相对较高~~
但是最好的算法不知道有没有其他~
Top
回复人:xuqian_2004(许前) ( 一级(初级)) 信誉:100 2005-09-04 01:55:00 得分:0
?
一般来说,匹配所需要的时间复杂度是与所需匹配的字符段长度有关,而与给的文章无关。
假设整个需要匹配的文章长度是m,其中匹配的模式长度是n
则有利用kmp算法,时间复杂度是O(m+n),如果使用改良以后的kmp算法,时间复杂度是O(n)
个人认为,这个时间复杂度已经很小了,因为一般来讲,模式的长度是比所给需扫描的文章长度小很多的。
对于3,4楼的算法来说,其实在实际运用中也还在使用,一般其复杂度在O(m+n)和O(m*n)之间。由于一般文章中重复的字串数量不多,所以应该接近O(m+n)。
以上是对时间复杂度的分析,下面算法指出模式中字符不匹配时每个字符应该对应平移的字符数,是kmp的精髓:
void move(String T ,int &next[])
{
i = 1 ;
next[1] = 0;
j = 0;
while( i<T[0] ) /*T[0]中存放着字符串的长度*/
{
if( j == 0 || T[i] = T[j] )
{
i++;
j++;
if( T[i] != T[j] )
{
next[i] = j ;
}
else
next[i] = next[j] ;
}
else
j = next[j] ;
}
}
以上是我的一点见解,还有其他算法的朋友希望能够多多指正,再加一点分析,希望大家共同进步。
Top
回复人:xuqian_2004(许前) ( 一级(初级)) 信誉:100 2005-09-04 01:56:00 得分:0
?
以上只是kmp中的一部分,不过已经是很关键的部分了。如果有朋友还不太明白kmp的话,可以查查相关的资料,省下的只是利用以上得出的数据进行具体操作而已,这里就不冗述了
Top
回复人:aseman(虚字佳人) ( 一级(初级)) 信誉:100 2005-09-04 02:13:00 得分:0
?
KMP吧...没有最好 只有更好 ...
Top
回复人:nanlan1984(小小) ( 一级(初级)) 信誉:100 2005-09-04 09:55:00 得分:0
?
大家都很厉害的哟
顺便问以一下大虾们 什么是KMP
Top
回复人:AAA235(可可豆) ( 一级(初级)) 信誉:100 2005-09-04 10:26:00 得分:0
?
KMP挺好
不过系统函数也不错的
const char *s1 = "12345678";
const char *s2 = "345";
char *p = strstr(s1,s2);
if(p == NULL)//没找到
...
else //找到
...
Top
回复人:mituzhishi(慎独) ( 二级(初级)) 信誉:100 2005-09-04 17:43:00 得分:0
?
楼上的各位高手为什么不用库函数呢?


你们都不用string吗?都是搞C的?


难道不知道库函数的效率很高吗?


#include <iostream>
#include <string>
#include <iostream>
using namespace std;


int main()
{
string str1("1234567891234567891234567879"),str2("91");
int index=-1,count=0;


while((index=str1.find(str2,index+1))!=string::npos)
count++;


cout<<str2<<" 在 "<<str1<<" 中出现了 "<<count<<" 次."<<endl;


return 0;
}
Top
回复人:tiger_ibm(bigfish) ( 一级(初级)) 信誉:100 2005-09-04 20:46:00 得分:0
?
不是解决办法,是考算法!
Top
回复人:fallening() ( 一级(初级)) 信誉:100 2005-09-04 20:50:00 得分:0
?
回复人:foochow(恰似你的温柔) 的算法是错误的
Top
回复人:qileroro(其乐融融) ( 一级(初级)) 信誉:100 2005-09-04 21:11:00 得分:0
?
C++沒有正則表達式的嗎?用正則兩句就搞定了。
Top
回复人:freshairfly(菜鸟精神) ( 四级(中级)) 信誉:110 2005-09-04 22:20:00 得分:0
?
KMP算法应该效率是最高的吧


刚看了《数据结构》,呵呵


库函数里的子串匹配一般应该还是使用的是普通的遍历回退的算法吧(这个偶不清楚,猜的)
Top
回复人:redleaves(ID最吊的网友) ( 五级(中级)) 信誉:110 2005-09-04 22:39:00 得分:0
?
通用匹配,KMP最快.O(m+n)
特定匹配,自动机最快.O(n)
Top
回复人:davysh(有望) ( 一级(初级)) 信誉:95 2005-09-05 10:01:00 得分:0
?
个人也比较同意kmp算法比库函数效率高的看法,不知有人测试过没有?
redleaves(ID最吊的网友) 说的自动机又是什么算法,请指教,是kmp的特例?
Top
回复人:redleaves(ID最吊的网友) ( 五级(中级)) 信誉:110 2005-09-05 14:13:00 得分:0
?
自动机在编译原理中讲过的.其实就是图灵机.再说得具体点,就是我们现在用的计算机.
它构造了很多状态,每接受一个输入状态都会变化.在词法分析中要用到.也可以用它来构造一个查找专用的自动机.当然,只能用来查找特定的内容(构造自动机时就决定了).KMP算法其实也算是一种自动机算法,它的Next就是自动机的状态.


比如:字符串中找aaa
┌---┐
↓ ↓ │
┌--[0]-a->[1]-a->[2]-a->[3]-a-┘
│ ↑ │ │ │
非a │ 非a 非a 非a
└---┴-----┴----┴------┘
初始状态为0,根据不同的输入决定下一个状态是什么.直到到达状态3就表示找到了.如果要计数的话在这时就可以加一.直到输入结束.


既然KMP也是一种自动机算法,为什么说特定匹配时用自动机(一般性的)最快呢?主要是因为KMP要照顾到通用性,有些优化没法做.一般性的自动机都是用查表来实现的,而不是用比较.所以在这点上,一般性的自动机要快一些.虽然也可以动态构造自动机的状态转换表,但它的代价比较大.相比就不如KMP了.
Top
回复人:redleaves(ID最吊的网友) ( 五级(中级)) 信誉:110 2005-09-05 14:14:00 得分:0
?
晕....我的图一提交就变形了..
Top
回复人:yazi321(菜鸟一个) ( 一级(初级)) 信誉:100 2005-09-05 19:04:00 得分:0
?
请问一下KMP算法是什么意思?
Top
回复人:Gelf() ( 一级(初级)) 信誉:100 2005-09-06 15:08:00 得分:0
?
题外话:
为什么for循环都喜欢用i++?用++i更好,省了临时变量
Top
回复人:jiang_xiao(原来秋天) ( 一级(初级)) 信誉:100 2005-09-06 20:50:00 得分:0
?
mark
Top
回复人:redleaves(ID最吊的网友) ( 五级(中级)) 信誉:110 2005-09-07 10:52:00 得分:0
?
TO Gelf():
i++和++i都不会产生临时变量,只是代码的顺序不一样罢了.
Top
回复人:cuterain(打雷下雨收衣服喽) ( 一级(初级)) 信誉:96 2005-09-12 08:52:00 得分:0
?
mark
Top
回复人:Bobby136(鄙视地球人!) ( 一级(初级)) 信誉:100 2005-09-12 09:00:00 得分:0
?
留名


to Gelf()


对于整型的i并非如此,不相信你测试一下就知道了
Top
回复人:niefuhua(阳光) ( 一级(初级)) 信誉:98 2005-09-16 11:42:00 得分:0
?
up






三.编写一个函数subs(char *str)打印出str的所有子串(例如1234的子串包
括:1,2,3,4,12,13,14,23,24,34,123,234,1234)不能使用系统提供的有关字符处理的类库,库函数.
四.
编写一个先入先出缓冲区的公共函数(或类库)程序.不限c c++.不能使用明显低效的方案
缓冲区的规则是:
1.缓冲区最大长度100m
2.向缓冲区存入数据时放在上次存入数据的后面
3.从缓冲区取出数据时,从缓冲区未被取走到数据的头部取.取出数据的缓冲区即可认为是空.以后杂再存入.
至少要为此缓冲区编写两个接口操作函数:
1.存入数据函数.第一个参数是int 长度值.第二个是指向二进制字节的指针.指向存入的数据.
2.取出数据函数.第一个参数是int 长度值.第二个是指字节的指针,指向取出数据后的内存位置.




第三题:
#include <iostream>
using namespace std;
int used[10] = {0};
void subs(char * s,int size,int b,int length,char * a,int k)
{
if (k == length)
{
for(int i = 0 ;i<k;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
}
for(int i = b;i<size;i++)
{
if (used[i] == 0)
{
used[i] = 1;
a[k] = s[i];
subs(s,size,i+1,length,a,k+1);
used[i] = 0;
}
}
}


void subsall(char * s,int size,char * a)
{
for(int i = 0;i<=size;i++)
{
subs(s,size,0,i,a,0);
}
}
int main()
{
char * s = new char[4];
s[0] = 'a';
s[1] = 'b';
s[2] = 'c';
s[3] = 'd';
char *a = new char[4];
subsall(s,4,a);
system("pause");
}
Top
回复人:zhouhuahai(道号"虚无") ( 三级(初级)) 信誉:100 2005-8-26 12:01:24 得分:0
?


三.全排列算法
参见:http://www.zahui.com/html/1/1633.htm
Top
回复人:SammyLan(没有窍门,只有努力.LOVE 33 4 Ever ) ( 二级(初级)) 信誉:98 2005-8-26 12:11:37 得分:0
?


MARK


Top
回复人:Ibanez119() ( 一级(初级)) 信誉:100 2005-8-26 13:13:09 得分:0
?


mark
Top
回复人:zhouhuahai(道号"虚无") ( 三级(初级)) 信誉:100 2005-8-26 13:38:30 得分:0
?


四.请参见<<C缺陷与陷阱>>中第X章有个实例.
具体第多少章忘了.
Top
回复人:songjie2004(我不会编程) ( 一级(初级)) 信誉:100 2005-8-26 15:16:30 得分:0
?


第4题在北京一个外包公司面试的时候见过,不过他们好像对我的答案不太满意。呵呵
Top
回复人:SammyLan(没有窍门,只有努力.LOVE 33 4 Ever ) ( 二级(初级)) 信誉:98 2005-8-26 17:00:46 得分:0
?


MARK


Top
回复人:zhr_23(zhr_23) ( 一级(初级)) 信誉:100 2005-8-28 16:21:05 得分:0
?


qhfu(崩溃) ,你第三题的思路是什么?答案不完整哦
如果是字符串全排列的思路?
Top
回复人:zhr_23(zhr_23) ( 一级(初级)) 信誉:100 2005-8-28 16:23:49 得分:0
?


第四题,看了很茫然不知道要干什么?
Top
回复人:foochow(恰似你的温柔) ( 一星(中级)) 信誉:100 2005-8-28 16:32:59 得分:0
?


3.
#include<iostream>
using namespace std;
const int n=100;
int a[n];
void prim(int m,int r)
{
int i,j;
i=0;
a[i]=1;
do
{
if(a[i]-i<=m-r+1)
{
if(i==r-1)
{
for(j=0;j<r;++j)cout<<a[j]<<" ";
cout<<endl;
a[i]=a[i]+1;
continue;
}
a[i+1]=a[i]+1;
i++;
continue;
}
else
{
if(i==0)break;
a[--i]++;
}
}while(1);
}
int main()
{
int n=1;
while(n<=4)
{
prim(4,n++);
}
system("PAUSE");
return 0;
}
Top
回复人:younggle(洋溢) ( 一级(初级)) 信誉:100 2005-8-28 16:45:08 得分:0
?


我在华为面试时做的编程题,他们根本没有认真看,只要你写了程序,有了一定的思路就可以了。
题目是:
编写一程序,实现2个无符号长整型数相加,注意溢出,结果以字符串输出。
函数原型为:
void CalcULongSum(IN unsigned long u1, IN unsigned long u2, OUT char *pchSumResult);


Top
回复人:lvjinhua(硬件&软件) ( 一级(初级)) 信誉:100 2005-08-28 21:15:00 得分:0
?
mark
Top
回复人:qhfu(崩溃) ( 一星(中级)) 信誉:105 2005-08-28 21:42:00 得分:0
?
qhfu(崩溃) ,你第三题的思路是什么?答案不完整哦
如果是字符串全排列的思路?
======================= 
我的答案是对的阿,思想就是:给定n个字符,上面一个函数是 求给定的k个字符的组合,下面一个函数是,通过调用上面一个函数求从1 到 n,的所有组合。
从给的题目看来并不是排列,应该是组合吧! 如果是排列,也可以就是把上面一个函数换成求排列的方法就好了。
Top
回复人:llf_hust() ( 五级(中级)) 信誉:100 2005-08-28 21:51:00 得分:0
?
up
Top
回复人:heguosheng(何国胜) ( 一级(初级)) 信誉:100 2005-08-29 13:10:00 得分:0
?
mark
Top
回复人:JohnTitor(努力学习) ( 四级(中级)) 信誉:100 2005-08-29 22:04:00 得分:0
?
void findsub(char *substr,char *str,int strLen,int substrLen,char *substrBeginPos)
{
if(substrLen == 0)
{
substr[0] = '\0';
std::cout<<substrBeginPos<<std::endl;
return;
}


for(int i=0;i<= strLen - substrLen;i++)
{
substr[0] = str[i];
findsub(substr + 1,str + i + 1, strLen - i - 1,substrLen -1,substrBeginPos);
}
}


void subs(char *str)
{
if(str == NULL)
return;
int strLen = strlen(str);
char *substr = new char[strLen + 1];
for(int substrLen = 1;substrLen <= strLen ;substrLen++)
{
findsub(substr,str,strLen,substrLen,substr);
}
delete [] substr;
}


main中调用subs("1234")
Top
回复人:archimedes0(狐冲) ( 一级(初级)) 信誉:100 2005-08-30 00:37:00 得分:0
?
很好,很好,接分了!
Top
回复人:Sophic(crazygug) ( 一级(初级)) 信誉:94 2005-08-30 17:12:00 得分:0
?
class MySingleton4
{
private:


MySingleton4(){ cout << _T("Construct MySingleton4") << endl; } //构造函数私有
~MySingleton4(){ cout << _T("Destroy MySingleton4") << endl; } //析构函数放哪里都可以了


static MySingleton4* _instance;


public:
static MySingleton4& GetInstanceRef()
{
if (_instance == 0)
_instance = new MySingleton4;
return *_instance;
}


static MySingleton4* GetInstancePtr()
{
return &GetInstanceRef();
}


static ReleaseInstance()
{
if (_instance != 0)
delete _instance;
}
};
怎么调用上在每个函数都不能运行呀??
Top
回复人:jinder22(jinder22) ( 一级(初级)) 信誉:100 2005-08-31 09:14:00 得分:0
?
这是我做的第三提的答案 使用了循环地归的办法
我已经在dev-c++中编译通过 欢银批评指正
#include <iostream>
using namespace std;
int sum=0;


char str[]="1234";
char str2[4];
int length;
char *out;






void DoCombine(char in[],char out[],int length,int rec,int start)
{


int i;
for(int i = start; i < length; i++)
{
out[rec] = in[i];
out[rec+1] =0;
printf("%s\n",out);
if(i< length-1)
DoCombine(in,out,length,rec+1,i+1);
}
}


int main(int argc, char* argv[])
{


length = strlen(str);
out = (char *)malloc(length +1);
DoCombine(str,out,length,0,0);
return 0;
}
Top
回复人:snowbirdfly(胡晋) ( 二级(初级)) 信誉:100 2005-08-31 10:39:00 得分:0
?
好啊~
收藏学习了~~
感谢~
Top
回复人:zoulie(珠峰菜鸟) ( 一级(初级)) 信誉:100 2005-08-31 10:43:00 得分:0
?
呵呵
收藏了啊
Top
回复人:yuanyou(元友) ( 二级(初级)) 信誉:100 2005-08-31 11:38:00 得分:0
?
mark
Top
回复人:jinder22(jinder22) ( 一级(初级)) 信誉:100 2005-08-31 13:22:00 得分:0
?
邦顶
Top
回复人:toxyboy(长的比较无奈) ( 二级(初级)) 信誉:100 2005-09-01 15:20:00 得分:0
?
第三题明显的是要考递归.
Mark
Top
回复人:bugebear3() ( 二级(初级)) 信誉:100 2005-09-01 16:52:00 得分:0
?
MARK
Top
回复人:lgk_jankey(过客) ( 一级(初级)) 信誉:100 2005-09-01 19:24:00 得分:0
?
弄回去看看先
Top
回复人:foochow(恰似你的温柔) ( 一星(中级)) 信誉:100 2005-09-01 20:12:00 得分:0
?
第三题回溯也可以
Top
回复人:MayhCat(MayhCat) ( 一级(初级)) 信誉:100 2005-09-09 16:02:00 得分:0
?
第3题:


void solute(char elements[], int len, char * path, int pos, int depth)
{
for ( int i=pos; i < len; i++ )
{
path[depth] = elements[i]; path[depth+1] = '\0';
cout << path << endl;
solute( elements, len, path, i+1, depth+1 );
}
}


void subs(char * str)
{
int len = 0;
while ( str[len] ) len++;
char * path = new char[len+1];
solute(str, len, path, 0, 0);
delete path;
}


int main()
{
subs("1234");


char ch;
cin.get(ch);
return 0;
}
Top
回复人:MayhCat(MayhCat) ( 一级(初级)) 信誉:100 2005-09-09 16:09:00 得分:0
?
更正:上delete path; 应为 delete []path;




5.
主  题: 我是菜鸟!面试题目,今天没做出来,但是希望得到答案。
作  者: superpengjiang ()
等  级:
信 誉 值: 100
所属论坛: C/C++ C++ 语言
问题点数: 100
回复次数: 52
发表时间: 2005-08-27 00:53:01


先谢谢啦!
在区间[0,10000]之间产生一万个随机整数,并将其存储到计算机上。
要求:
1.存储的数据不能够有重复;
2.找出在[0,10000]中没重复的数据。
回复人:sakaer(sakaer) ( 一级(初级)) 信誉:100 2005-08-27 01:07:00 得分:0
?
说的明白一些哦,产生一万个随机整数,但是区间只有[0,10000],一共只有10001个整数,你先说得存储到计算机上,然后又说不能重复,那这样存储的肯定不够一万个的。
如果只是保证没有重复的话,你可以使用vector一类的容器保存产生的整数,只要在押入数据的时候先用find函数查找一下就可以了,等所有的随机数产生以后再把vector中的数写到计算机上就好了。
Top
回复人:foochow(恰似你的温柔) ( 一星(中级)) 信誉:100 2005-08-27 01:21:00 得分:0
?
#include<iostream>
#include<vector>
#include<ctime>
using namespace std;
int main()
{
vector<int>temp(100001,0);
srand(time(0));
int n=10001;
while(--n)
{
int t=rand()%10001;
if(!temp[t])temp[t]=1;
}
for(int i=0;i<10001;++i)
if(temp[i])cout<<i<<" ";
cout<<endl;
return 0;
}
Top
回复人:foochow(恰似你的温柔) ( 一星(中级)) 信誉:100 2005-08-27 01:30:00 得分:0
?
上面写多了,应该是
vector<int>temp(10001,0);
Top
回复人:y0z0(荒山之夜) ( 一级(初级)) 信誉:100 2005-08-27 04:23:00 得分:0
?
这不就是应该用Hash Table来做啊
Top
回复人:weaker() ( 一级(初级)) 信誉:100 2005-08-27 08:06:00 得分:0
?
using namespace std;
是什么意思啊
Top
回复人:yyj1982(一切从头开始,好好学英语) ( 二级(初级)) 信誉:100 2005-08-27 08:08:00 得分:0
?
foochow(恰似你的温柔) ( )


写的不错!!!
避免了查找!!


学习中!!!!
Top
回复人:zhouhuahai(道号"虚无") ( 三级(初级)) 信誉:100 2005-08-27 09:10:00 得分:0
?
foochow(恰似你的温柔)
的做法不能符合要求,因为不会产生足够的数.题目要求是产生一万个随机整数.
Top
回复人:zhouhuahai(道号"虚无") ( 三级(初级)) 信誉:100 2005-08-27 09:12:00 得分:0
?
在区间[0,10000]之间产生一万个随机整数,并将其存储到计算机上。
而且数据不能重复?
那么区间内的10001个数只有一个数不在其中了.先用rand()产生出这个数,其它的全在这个范围之内了


不知我的理解是否正确?
Top
回复人:jixingzhong(瞌睡虫(既然选择了远方,那就只有风雨兼程了!!)) ( 五级(中级)) 信誉:101 2005-08-27 09:36:00 得分:0
?
这个问题我看到过了啊
楼主没有解决? 还是其他的原因呢 ?


我想到了一个解决问题的办法,如果用的是 RAND(),虽然是随即的,但是在 10000/10001 的密度下,基本上要不重复是不可能的 !


我的想法是反过来,我们可以得到一个在[0,10000]中的随即数 ,因为这个数是随即的 ,那么,剩下的10000个数也是随即的,符合楼主的随即性的要求 !
保存的话也是很简单的,一个循环就是了
(这样的话要每个数据都要比较是否是这个选出来的 例外随即数,
如果不想比较的话,做辆次循环就是了: [0,N),(N,10000] )...
Top
回复人:qhfu(崩溃) ( 五级(中级)) 信誉:105 2005-08-27 09:47:00 得分:0
?
楼主的问题有点奇怪! 10001个产生10000个, 这个好像比较奇怪! 不是跟发牌程序一样了吗? 呵呵
Top
回复人:Bobby136(鄙视地球人!) ( 一级(初级)) 信誉:100 2005-08-27 11:21:00 得分:0
?
给你一个比较高效的答案


int a[10000];


for(int i=10000;i>0;)
{
a[0]=rand()%i;
swap(a[0],a[--i]);
}
Top
回复人:Bobby136(鄙视地球人!) ( 一级(初级)) 信誉:100 2005-08-27 11:32:00 得分:0
?
上面的有错,下面的差不多了


int a[10000];
int tmp;
for(int i=0;i<10000;i++)a[i]=i;
for(i=10000;i>0;)
{
tmp=rand()%i;
swap(a[tmp],a[--i]);
}
Top
回复人:Bobby136(鄙视地球人!) ( 一级(初级)) 信誉:100 2005-08-27 11:52:00 得分:0
?
如果一定要使10001个熟的话,把数组大小改为10001,取前10000个,最后a[10000]就是没有取的数


int a[10001];
int tmp;
for(int i=0;i<10001;i++)a[i]=i;
for(i=10001;i>0;)
{
tmp=rand()%i;
swap(a[tmp],a[--i]);
}
Top
回复人:husl(呼哨) ( 一级(初级)) 信誉:100 2005-08-27 21:13:00 得分:0
?
支持 恰似你的温柔


题目意思应该是在 1 到10000之间产生10000个随机数 , 然后把其中不重复出现过 存储到计算机吧


恰似你的温柔 的方法很好啊, 好像是哈序表的 原理
Top
回复人:husl(呼哨) ( 一级(初级)) 信誉:100 2005-08-27 21:16:00 得分:0
?
不重复出现过 -->没有重复出现过的
Top
回复人:Bobby136(鄙视地球人!) ( 一级(初级)) 信誉:100 2005-08-27 22:10:00 得分:0
?
恰似你的温柔


你的算法产生的随机数怎么基本上是从小到大排列的,不是随机的
Top
回复人:KeepSilence84125(单身贵族) ( 一级(初级)) 信誉:100 2005-08-27 22:46:00 得分:0
?
不太懂:“2.找出在[0,10000]中没重复的数据。”是什么意思?


支持 foochow(恰似你的温柔) 用空间换时间的方法,
不过他好像没有产生足够的10000个,也没有按产生顺序存储产生数,只是按大小输出所产生数
Top
回复人:021850524(吸血鬼牌卫生巾) ( 四级(中级)) 信誉:76 2005-08-28 00:07:00 得分:0
?
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int buf[10000];
for(int i=0; i<10000; ++i)
{
buf[i] = i + 1;
}
random_shuffle(buf, buf + 10000);//buf中内容即为所求.
return 0;
}
Top
回复人:SammyLan(没有窍门,只有努力.LOVE 33 4 Ever) ( 二级(初级)) 信誉:98 2005-08-28 00:22:00 得分:0
?
鄙视地球人正解
这个题目一年前就做过了 (=_=)
Top
回复人:SammyLan(没有窍门,只有努力.LOVE 33 4 Ever) ( 二级(初级)) 信誉:98 2005-08-28 00:54:00 得分:0
?
int Rand()
//生成SIZE位的随机数0<(SIZE<10)
//返回一个各位数都不相同的随机数
{
static int ver[SIZE+1];
static int size=SIZE+1;
static bool bInit=false;
if (!bInit) {
srand(unsigned(time(0)));
bInit=true;
for (int i=0;i<=size;++i) {
ver[i]=i;
}
}


if (!size) {
size=SIZE+1;
}
int i=rand()%size;
int _Rand=ver[i];
--size;
ver[i]=ver[size];
ver[size]=_Rand;
return _Rand ;
}


我要100分 (=_=)
Top
回复人:SammyLan(没有窍门,只有努力.LOVE 33 4 Ever) ( 二级(初级)) 信誉:98 2005-08-28 00:55:00 得分:0
?
注释写错
Top
回复人:jyk(喜欢编程。和气生财。共同提高。共同进步) ( 一级(初级)) 信誉:100 2005-08-28 07:15:00 得分:0
?
在区间[0,10000]之间产生一万个随机整数,并将其存储到计算机上。
要求:
1.存储的数据不能够有重复;
2.找出在[0,10000]中没重复的数据。




题意不明确,会产生异议。


我赞同 Bobby136(鄙视地球人!) 的写法,这样才有实际的意义。


否则的话没有什么意义了。
Top
回复人:xiajia(贾胜华) ( 一级(初级)) 信誉:100 2005-08-28 09:29:00 得分:0
?
我也来讨论一下!
1、正面解决问题,将数据保存到数组(0-10000),随机提出一个数据,保存到目标数组中,然后清空这个数组元素,整理数组剔除所有提出的元素。这样数组大小为(0-9999),重复这个工作直到取出10000为止。这样的在计算量和存储空间上都是很大的开支!
2、反面结局这个问题:上面已经有朋友说了,提出一个随机数据,留下的需要的,为了使留下的数据在排列上有随机性,可以进行n/2次的随机交换。
Top
回复人:SammyLan(没有窍门,只有努力.LOVE 33 4 Ever) ( 二级(初级)) 信誉:98 2005-08-28 10:09:00 得分:0
?
template<int SIZE>
//产生一个0~SIZE的随机数
int Rand()
{
static int ver[SIZE+1];
static int size=SIZE+1;
static bool bInit=false;
if (!bInit) {
srand(unsigned(time(0)));
bInit=true;
for (int i=0;i<=size;++i) {
ver[i]=i;
}
}


if (!size) {
size=SIZE+1;
}
int i=rand()%size;
int _Rand=ver[i];
--size;
ver[i]=ver[size];
ver[size]=_Rand;
return _Rand ;
}
Top
回复人:SammyLan(没有窍门,只有努力.LOVE 33 4 Ever) ( 二级(初级)) 信誉:98 2005-08-28 10:13:00 得分:0
?
保证用这个产生的话
前SIZE次不回产生重复 (=_=)
Top
回复人:ruodeer(一直在大连) ( 一级(初级)) 信誉:100 2005-08-28 10:27:00 得分:0
?
没明白楼主的意思,到底是结果是10000个不重复随机数 //这样就简单了
还是取10000个随机数然后找出不重复出现的存起来……
Top
回复人:lvjinhua(硬件&软件) ( 一级(初级)) 信誉:100 2005-08-28 10:28:00 得分:0
?
#include<vector>
#include<iostream>
#include<ctime>
using namespace std;
int main()
{
vector<int> r(10001,1); //申请空间并初始化为1
srand(time(0));
int i=rand()%10001; //产生那个唯一的数
r[i] = 0; //标记此唯一的数
for(int j=0;j<10001;++j)
if( j != i )
cout<<j<<' ';
return 0;
}
Top
回复人:megaboy(飞天御剑流之杀神一刀斩) ( 五级(中级)) 信誉:100 2005-08-28 10:40:00 得分:0
?
这个问题8月23日已经有另一个叫黑色闪电的人问过了,并已结贴,我已经给出了答案,请参考http://community.csdn.net/Expert/topic/4227/4227361.xml?temp=.3957331


我的答案如下:


#include <stdio.h>
#include <time.h>
#include <stdlib.h>


int iNum[10000];


int main(void)
{
int i, iRemain, iTemp;
srand((unsigned)time(NULL));
iRemain = rand()%10001; //首先产生没有出现的那个数
for(i=10000; i>=1; i--) //这里不需要考虑i=0,因为最后一个就是0
{
if(i == iRemain) continue; //把那个没有出现的数剔除
while(1)
{
iTemp = rand()%10000;
if(iNum[iTemp] == 0)
{
iNum[iTemp] = i;
break;
}
}
}
printf("The number not generated is %d", iRemain);
return 0;
}


所产生的随机数列放在iNum数组里面,iRemain存放那个没出现的数。
Top
回复人:SammyLan(没有窍门,只有努力.LOVE 33 4 Ever) ( 二级(初级)) 信誉:98 2005-08-28 10:41:00 得分:0
?
开始理解错题意了 (=_=)
int const SIZE=10001;
struct VER
{
int iVal;
int iCount;
}ver;
for(int i=0;i<SIZE;++i)
{
ver[i].iVal=-1;
ver[i].iCount=0;
}
for(int i=0;i<SIZE;++i)
{
int temp=rand()%SIZE;
ver[temp].iVal=temp;
++ver[temp].iCount;
}
for(int i=0;i<SIZE;++i)
if(ver[i].iVal>=0)cout<<setw(6)<<ver[i].iVal;
cout<<endl;
for(int i=0;i<SIZE;++i)
if(ver[i].iCount==1)cout<<setw(6)<<ver[i].iVal;
Top
回复人:megaboy(飞天御剑流之杀神一刀斩) ( 五级(中级)) 信誉:100 2005-08-28 11:30:00 得分:0
?
原始的方法,是先产生一个随机数,把它放进iNum[0],然后再产生另一个,放进iNum[1],一直到iNum[9999],但每产生一个随机数,都要跟前面的随机数进行比较,以免出现重复,这种比较要花费大量的时间,越往后次数越多,效率太低。


我的方法,是按顺序产生那10001个数:for(i=10000; i>=1; i--),0因为是最后一个,不需要考虑。然后随机产生它们在iNum[]中的位置iTemp,由于iNum是全局数组,一开始它被自动初始化为零,如果 iNum[iTemp]为零,表示这个位置还没被使用过,就把i赋予它,如果不为零,表示这个位置已被使用了,就重新随机产生另一个位置,直到找到适合的位置。最后的0不需要随机产生位置,因为它是最后一个。这样就免去了象原始方法那样逐个比较随机数产生的大量开销,速度快得多了。
Top
回复人:wangchao2824(w&c) ( 一级(初级)) 信誉:100 2005-08-28 15:43:00 得分:0
?
for(i=0;i<10001;i++)
{
randamize(100001)
Top
回复人:wangchao2824(w&c) ( 一级(初级)) 信誉:100 2005-08-28 15:43:00 得分:0
?
for(i=0;i<10001;i++)
{
randamize(100001)
Top
回复人:wangchao2824(w&c) ( 一级(初级)) 信誉:100 2005-08-28 15:47:00 得分:0
?
long i,*a;
for(i=0;i<10001;i++)
{
randomize()
*a++=rand();
}
Top
回复人:SammyLan(没有窍门,只有努力.LOVE 33 4 Ever) ( 二级(初级)) 信誉:98 2005-08-28 16:34:00 得分:0
?
题目没有理解清楚,估计是这样的吧


struct VER
{
int iVal;
int iCount;
}ver[SIZE];
for(int i=0;i<SIZE;++i)
{
ver[i].iVal=-1;
ver[i].iCount=0;
}
for(int i=0;i<SIZE;++i)
{
int temp=rand()%SIZE;
ver[i].iVal=temp;
++ver[temp].iCount;
}
for(int i=0;i<SIZE;++i)
if(ver[i].iVal>=0&&ver[ver[i].iVal].iCount==1)
cout<<setw(6)<<ver[i].iVal; //这些数据都是
cout<<endl;
Top
回复人:zhr_23(zhr_23) ( 一级(初级)) 信誉:100 2005-08-28 16:59:00 得分:0
?
楼主意思是象随机洗牌一样,没有重复的得到各张牌吧。
但是你的意思好象是10001个数,抽出10000个不重复的随机数了。
#include<iomanip.h>
#include<iostream.h>
#include<time.h>
#include<stdlib.h>
void main()
{
const N=10001;
int data[N];
for(int j=0;j<N;j++)
data[j]=j;
cout<<setw(20)<<"生成0-"<<N-1<<"之间且不重复的随机数"<<endl;
cout<<"----------------------------------"<<endl;
srand((unsigned)time(0));//由系统时间生成随即数
for(int i=0;i<N-1;i++)
{
int tem=rand()%N;//限制在0到N-1之间
int k=data[i];
data[i]=data[tem];
data[tem]=k;
}
cout<<"---------------------------------"<<endl;
for(int m=0;m<N-1;m++)
cout<<setw(3)<<data[m];
cout<<endl;
}
Top
回复人:jinder22(jinder22) ( 一级(初级)) 信誉:100 2005-08-28 22:16:00 得分:0
?
这道题绝对不同于洗牌程序 支持恰似你的温柔
在区间[0,10000]之间产生一万个随机整数 当然有可能产生重复的 比如4000重复 6000不重复
那就把那些不重复的存储在队列里 结果很有可能就是几千个
然后把他们打硬出来就可以了
Top
回复人:megaboy(飞天御剑流之杀神一刀斩) ( 五级(中级)) 信誉:100 2005-08-29 07:58:00 得分:0
?
楼上的连题目的意思都没看清楚,你们看看楼主是怎么说的?


1.存储的数据不能够有重复;
2.找出在[0,10000]中没重复的数据。




其实楼主在第二条上有些字眼写错了,“没重复”应该是“没出现”。


整个题目的意思就是在闭区间[0, 10000]之中有从0到10000共10001个数,在这10001个数中随机产生10000个不重复的数,那么就肯定有一个没在数列中,保存这个数列,同时找出那个没有出现的数。
Top
回复人:jinder22(jinder22) ( 一级(初级)) 信誉:100 2005-08-29 14:30:00 得分:0
?
楼上的你胡说 你还篡改楼主的题目
人家说产生10000个随机数 当然有可能又重复的 保存在电脑里面的可能只有几千个
只要那几千个没有重复就行 你先把题目看清楚在来说我!!
按你的意思说 要产生10000个不重复的数 题意又没这么说不重复的数一定是10000
Top
回复人:jinder22(jinder22) ( 一级(初级)) 信誉:100 2005-08-29 15:01:00 得分:0
?
dddddddddddddddddddddd
Top
回复人:megaboy(飞天御剑流之杀神一刀斩) ( 五级(中级)) 信誉:100 2005-08-29 15:07:00 得分:0
?
哎,哎,几千个没有重复的就行???


你是怎么看题目的啊?????再看看!!楼主人家是怎么写的?????


----------------------------------------------
先谢谢啦!
在区间[0,10000]之间产生一万个随机整数,并将其存储到计算机上。
要求:
1.存储的数据不能够有重复;
2.找出在[0,10000]中没重复的数据。
-----------------------------------------------


人家要求是一万个随机整数啊!!!!!!看见没?而且这10000个不能有重复哦。[0, 10000]是个闭区间,共有10001个整数,随机产生其中的10000个,存储的数据不能有重复,那么就会只剩下一个没有产生出来的,就要找出那一个。在说别人纂改之前先自己好好想清楚。
Top
回复人:megaboy(飞天御剑流之杀神一刀斩) ( 五级(中级)) 信誉:100 2005-08-29 15:37:00 得分:0
?
楼主有些字眼写错了,造成歧义,下面链接是这个题目的正版,呵呵。


http://community.csdn.net/Expert/topic/4227/4227361.xml?temp=.3957331
Top
回复人:yajyjy(木易) ( 一级(初级)) 信誉:100 2005-08-29 15:58:00 得分:0
?
Bobby136(鄙视地球人!)
思路简单高效
Top
回复人:benjiam() ( 二级(初级)) 信誉:100 2005-08-29 16:16:00 得分:0
?
int a[10001];
int tmp;
for(int i=0;i<10001;i++)a[i]=i; //此处改为i < 10000
for(i=10001;i>0;)
{
tmp=rand()%i;
swap(a[tmp],a[--i]);
}




那么每次没有出现的数据都的数据固定的, 不符合题义吧。 不过洗牌技术很简洁。但是洗牌的效果能做一个科学的分析吗? 这个只是保证了每个数据都交换一次
Top
回复人:donnyfox(唐朝) ( 一级(初级)) 信誉:100 2005-08-29 16:33:00 得分:0
?
将一万个苹果放到一万个格子里面。
按顺序取苹果,但不按顺序放,随机放。
这样就只要一次循环,且保证了随机性。
每次判断也只用判断这个格子是否已经放了苹果,若放了,则再取随机数,直到那个格子是空的,继续放入。
Top
回复人:benjiam() ( 二级(初级)) 信誉:100 2005-08-29 17:03:00 得分:0
?
按顺序取苹果,但不按顺序放,随机放。
这样就只要一次循环,且保证了随机性。
每次判断也只用判断这个格子是否已经放了苹果,若放了,则再取随机数,直到那个格子是空的,继续放入


这样的插入曲线 是不平滑的 到最后冲突很多 很多
Top
回复人:jinder22(jinder22) ( 一级(初级)) 信誉:100 2005-08-30 11:21:00 得分:0
?
存储的数据不能够有重复 并不代表产生的没重复 就好像你有10000张1元的票子 有真钞 有假钞
但存储的只能是真钞 这样实际上存储的显然小于10000
也就是 产生10000个随机数 择优存储而已
而Bobby136(鄙视地球人!)的做法是有悖题意的!!
Top
回复人:jinder22(jinder22) ( 一级(初级)) 信誉:100 2005-08-30 11:39:00 得分:0
?
#include<iostream>
#include<vector>
#include<ctime>
#include <stdio.h>
#include <stdlib.h>


using namespace std;
int main()
{
int randtmp;
vector<int>temp(11,0); //空间大小为11 默认值为0
srand(0);




int n=11;
while(--n)
{




int t=rand()%11;


if(temp[t]==0)
{
temp[t]=1;
cout<<"\n tttt"<<t; //如果这个数字没有出现过 则存储它 并标记temp[t]=1
//代表已经存储过
}
else
{
cout<<"\n ffff"<<t;
}
}
for(int i=0;i<11;++i)
if(temp[i]==0) cout<<"\n "<<i; //如果temp[i]==0 则代表他没有出现过
cout<<endl;
return 0;
}


至于算法产生的随机数怎么基本上是从小到大排列的,但仍然是随机的 只不过把随机数从小到大排一遍而已 这个到无所谓 题目没说不许排序 觉得不爽的话 在重新打乱就是 不过实在没有必要
Top
回复人:Bobby136(鄙视地球人!) ( 一级(初级)) 信誉:100 2005-08-30 15:09:00 得分:0
?
题目有歧义
Top
回复人:Bobby136(鄙视地球人!) ( 一级(初级)) 信誉:100 2005-08-30 15:13:00 得分:0
?
“并将其存储到计算机上。”里面的“其”字指的就是10000个随机数。
Top
回复人:Bobby136(鄙视地球人!) ( 一级(初级)) 信誉:100 2005-08-30 15:17:00 得分:0
?
面试官误人子弟,出的题目叫人怎么做!!
还有 张三李四下棋,找出李四必胜的所有情况那题,也是个错题,或者题目没有表达他要表达的意思!!!
Top
回复人:megaboy(飞天御剑流之杀神一刀斩) ( 五级(中级)) 信誉:100 2005-08-31 08:23:00 得分:0
?
其实题目并没有产生歧义,只是有些人没法理解楼主的意思而已,不过,楼主的确写错了两个字,没重复应该是没出现,但这个错误对题目的本意影响很小。这些人理解错误的地方就在于第一个要求,把人家一个文字上的要求理解成一个动作,人家只是要求这10000个随机数里面没有重复的,仅此而已。如果第一个要求是这样写的:去掉其中重复的数据。那么就是这些人所理解的意思了。问题在那些人身上,而不是在楼主。




楼上的朋友,其实你的方法是最好的。包括你的方法,现在我知道了两种可以快速处理这类问题的方法,你的方法除了快速之外,还有一个很好的地方:不需要刻意地产生那个没出现的数,也并非象你所说的a[10000]才是没出现的数,而是随便一个元素都可以成为那个没出现的数!但是你被人说了两句,就开始动摇了,立场不坚定了,开始不相信自己了,这样子做人可不好哦,你会失去很多本应属于你的东西的,迟早。


不过,你说的张三李四下棋倒的确是个错题,还有张三李四抽牌那个题,找出张三必抽最后一张那题,也是错题,题目的意思是自相矛盾的。
Top
回复人:vc_tapi(为了爱) ( 一级(初级)) 信誉:100 2005-09-08 21:24:00 得分:0
?
up
Top


6.
主  题: 请教:华为面试题
作  者: kasad ()
等  级:
信 誉 值: 100
所属论坛: C/C++ C语言
问题点数: 100
回复次数: 60
发表时间: 2005-9-4 12:07:23




#include <stdio.h>
void main()
{
union
{
struct
{
unsigned short s1:3;
unsigned short s2:3;
unsigned short s3:3;
}x;
char c;
}v;
v.c=100;
printf("%d\n",v.x.s3);
}
A:4 B:0 C:3 D:6
答案是A
但我在TURBO C中运行答案是1
请问 是因为TURBO C 版本在原因而运行结果不一样吗?
我用在TURBO C V2.0版本
能解释一下为甚么是4或1?
而v.x.s1和v.x.s2的 值 在TURBO C V2.0版本运行的结果是4?
其中unsigned short s1:3; 中的“:”又是什么意思?
回复人:vc_feeling(小菠菜) ( 一级(初级)) 信誉:100 2005-9-4 12:37:37 得分:5
?


结构struct x,有三个成员s1,s2,s3每一个成员占3 bit,
结构与char c union ;
char 一般机器占一个字节(8 bit ),100 二进制值为:01100100,所以s1后三bit(6,7,8 bit) :100
s2为中间三位(3,4,5 bit)为100 s1为01,所以printf("%d\n",v.x.s3)是1,其它是4


Top
回复人:Bobby136(鄙视地球人!) ( 一级(初级)) 信誉:100 2005-9-4 12:40:12 得分:5
?


位域
2 3 3
01 100 100


如果先申明的在低位,就是4
先申明在高位就是1
Top
回复人:suwenhb() ( 一级(初级)) 信誉:100 2005-9-4 12:54:18 得分:0
?


用vc跑了一下,是1
Top
回复人:tongyongmc(fengyun) ( 二级(初级)) 信誉:100 2005-9-4 12:59:46 得分:5
?


"s2为中间三位(3,4,5 bit)为100 s1为01,所以printf("%d\n",v.x.s3)是1,其它是4"


s3 的最高位应该是未知的吧? 内存中的形式: ?01


那么 s3 = 1 的结果会不会只是凑巧而已,,


s3 可能会有 1、3两种结果?
Top
回复人:ruiding(瑞丁) ( 一级(初级)) 信誉:100 2005-9-4 13:12:09 得分:5
?


现在大多数系统都是将低字位放在前面,而结构体中位域的申明一般是先声明高位。


100 的二进制是 001 100 100


低位在前 高位在后


001----s3


100----s2


100----s1


所以结果应该是 1


如果先申明的在低位则:


001----s1


100----s2


100----s3


结果是 4




Top
回复人:duduhu(嘟嘟虎) ( 一级(初级)) 信誉:100 2005-9-4 13:13:36 得分:5
?


先声明的放高位还是低位是由谁来决定的呢?
100的二进制是01100100在9位的地址空间中是放高位还是放低位呢?
Top
回复人:zhouhuahai(道号"虚无") ( 四级(中级)) 信誉:100 2005-9-4 13:20:08 得分:5
?


其中unsigned short s1:3; 中的“:”又是什么意思?
指定位段, 3代表预定s1占3bit.


为什么是4?
struct
{
unsigned short s1:3; //一个字节. 虽然预定为3bit,但系统的存储空间为至少一字节.
unsigned short s2:3; //一个字节
unsigned short s3:3; //一个字节
}x;
这样在联合union中最大的成员为三个字节,而最终结果为了内存对齐(对齐为4的倍数).取为4!


其它问题楼上已经给出了答案.


Top
回复人:zhouhuahai(道号"虚无") ( 四级(中级)) 信誉:100 2005-9-4 13:28:02 得分:0
?


看错了题,偶还以为是求union v的sizeof(),不好意思


另外,偶的说法有误:


应该是按指定位段来求总的size,并在最后取整为2的幂.
上面的题,如果要求sizeof的话,应该是:
3+3+3=9bit,再取整为两个字节(2的一次幂).
Top
回复人:phoenixsharp(小星星) ( 一级(初级)) 信誉:100 2005-9-4 13:44:57 得分:5
?


不是吧....低位肯定是放在低地址...看看我的分析.大家讨论一下:
v.c= 100 (01100100) -->low:0100 high:0110
union 后的存储分布是这样:
char c: 0 1 0 0 0 1 1 0
struct: x.s1 x.s2 x.s3
value : 010 001 10(0)
由于char 是8 位长度.x 是9位.union 显示x比c要多一位.s3的位域是3位的.所以后面被0 取出的结果为100,即十进制的4.
大家看看是不是这个样子...华为一般不会出结果比较含糊的题吧..这么大一个公司..肯定会避免有多种答案的面试题.呵呵...
Top
回复人:wanguodu(足文字D) ( 一级(初级)) 信誉:100 2005-9-4 13:53:27 得分:5
?


华为的这个题是出得有问题的。在little endian机器上(如PC)答案为1;在big endian机器上答案才是4。可能出题这个人是做PowerPC开发板的,呵呵。
CPU字节序不同,bit存放的顺序也会不同的。
Top
回复人:elvispl(Elvis) ( 一级(初级)) 信誉:100 2005-9-4 14:25:11 得分:5
?


答案4


二、位结构
位结构是一种特殊的结构, 在需按位访问一个字节或字的多个位时, 位结构
比按位运算符更加方便。
位结构定义的一般形式为:
struct位结构名{
数据类型 变量名: 整型常数;
数据类型 变量名: 整型常数;
} 位结构变量;
其中: 数据类型必须是int(unsigned或signed)。 整型常数必须是非负的整
数, 范围是0~15, 表示二进制位的个数, 即表示有多少位。
变量名是选择项, 可以不命名, 这样规定是为了排列需要。
例如: 下面定义了一个位结构。
struct{
unsigned incon: 8; /*incon占用低字节的0~7共8位*/
unsigned txcolor: 4;/*txcolor占用高字节的0~3位共4位*/
unsigned bgcolor: 3;/*bgcolor占用高字节的4~6位共3位*/
unsigned blink: 1; /*blink占用高字节的第7位*/
}ch;
位结构成员的访问与结构成员的访问相同。
例如: 访问上例位结构中的bgcolor成员可写成:
ch.bgcolor


注意:
1. 位结构中的成员可以定义为unsigned, 也可定义为signed, 但当成员长
度为1时, 会被认为是unsigned类型。因为单个位不可能具有符号。
2. 位结构中的成员不能使用数组和指针, 但位结构变量可以是数组和指针,
如果是指针, 其成员访问方式同结构指针。
3. 位结构总长度(位数), 是各个位成员定义的位数之和, 可以超过两个字
节。
4. 位结构成员可以与其它结构成员一起使用。
例如:
struct info{
char name[8];
int age;
struct addr address;
float pay;
unsigned state: 1;
unsigned pay: 1;
}workers;'
上例的结构定义了关于一个工从的信息。其中有两个位结构成员, 每个位结
构成员只有一位, 因此只占一个字节但保存了两个信息, 该字节中第一位表示工
人的状态, 第二位表示工资是否已发放。由此可见使用位结构可以节省存贮空间。


Top
回复人:wanguodu(足文字D) ( 一级(初级)) 信誉:100 2005-9-4 14:35:05 得分:0
?


多说无用,elvispl(Elvis)老弟你不妨亲自动手在VC上一试,何如?
Top
回复人:heguosheng(何国胜) ( 一级(初级)) 信誉:100 2005-9-4 14:54:02 得分:0
?


up
Top
回复人:zpzs(zpz) ( 一级(初级)) 信誉:100 2005-9-4 17:54:23 得分:5
?


应该是考语言, 而不是编译器.
语言的规定是高层次的, 具体到编译器才分高低位. 从这个思路考虑会好一点.
另外不要一遇到问题就上机调试, 问题没搞清楚就上机好像离不开机器似的.
Top
回复人:luwy() ( 一级(初级)) 信誉:100 2005-9-4 18:22:01 得分:5
?


各位兄弟别争了
现在字节的顺序有两种方式
1big-endian 现在被大多数采用 如IBM Motorola 和SUN microsystem
2 little-endian 如Digital eqipment corperation(now part of compaq corperaton) 和intel
明显你的机子是PC,所以是little-endian
s3 s2 s1
100 100 01 组合后就是01100100也就是100
所以结果是4,他给的结果
Top
回复人:lyclowlevel(蓬蒿人) ( 二级(初级)) 信誉:100 2005-9-4 18:23:56 得分:0
?


up
Top
回复人:wanguodu(足文字D) ( 一级(初级)) 信誉:100 2005-9-4 18:38:15 得分:0
?


100——》0x1100100,在LE的机器上,BIT按从低到高的顺序存储,所以应该是:
s1=0x100, s2=0x100, s3=0x1, 结果是1,suwenhb的实践结果也证明了这一点。相反在BE的机器上,结果是4。
华为的人不是神仙哪,考虑问题也会有失偏颇的。
Top
回复人:wanguodu(足文字D) ( 一级(初级)) 信誉:100 2005-9-4 18:44:45 得分:3
?


喔,回复中有个笔误,应该是 100-->1100100b
Top
回复人:wanguodu(足文字D) ( 一级(初级)) 信誉:100 2005-9-4 18:46:57 得分:0
?


还有,s1=100b=4, s2=100b=4, s3=1。十六进制用惯了!
Top
回复人:SammyLan(没有窍门,只有努力.LOVE 33 4 Ever ) ( 二级(初级)) 信誉:96 2005-9-4 20:29:54 得分:0
?


肯定是1 (=_=)


Top
回复人:shmilvy() ( 一级(初级)) 信誉:100 2005-9-4 20:50:34 得分:5
?


肯定是1
我在那个TURC 3.0运行是1
肯定滴.....
Top
回复人:shockwave_115(采姑娘的小蘑菇) ( 一级(初级)) 信誉:100 2005-9-4 23:56:10 得分:5
?


big-endian
little-endian 不是有一个考题让人写个简单程序判断是big-endian还是little-endian就是用这个办法么?机子不同结果当然不同
Top
回复人:na1ve(柴青) ( 一级(初级)) 信誉:100 2005-9-5 0:15:45 得分:5
?


可能这个职位有具体的应用环境,一般微机上应该答案是1。属于Little endian
Top
回复人:wanguodu(足文字D) ( 一级(初级)) 信誉:100 2005-9-5 8:58:09 得分:0
?


shockwave_115兄弟: 位段还有如此妙用,高实在是高啊!
Top
回复人:showwecumt(眼皮) ( 一级(初级)) 信誉:100 2005-9-5 9:19:01 得分:5
?


考得也太细了,汗。。。。。。。。
Top
回复人:kasad() ( 一级(初级)) 信誉:100 2005-9-5 10:41:57 得分:0
?


随便再问个问题,这是我以前问过的一个问题,也是华为面试题:
下面哪种存储单位更小,为什么?
struct name{
char* str;
int num;
}


struct name{
int num;
char* str;
}




Top
回复人:ruodeer(一直在大连) ( 一级(初级)) 信誉:100 2005-9-5 11:20:49 得分:0
?


学习来了
Top
回复人:dhy311(好好学习,天天向上) ( 三级(初级)) 信誉:99 2005-9-5 11:31:56 得分:3
?


pc上面是1,powerpc上面是0(vc6.0,windowsxp),
pc上面是:100, 100, 001 ( 001100100 = 100 ) ,低位放在低内存
powerpc上面是:011,001,000(01100100 = 100 ),高位放前面(codewarrior + macosx)


如果是高位放前面,是再后面补上不足的位,powerpc就是再最后面添加了一个0,
如果是低位放前面,那就是再高位补上不足的位
Top
回复人:wanguodu(足文字D) ( 一级(初级)) 信誉:100 2005-9-5 11:33:56 得分:0
?


kasad: 你记错了吧,两个结构占用存储是一样的,如果char* str改为char str就有区别了。
Top
回复人:hansin(将冰山劈开) ( 一级(初级)) 信誉:100 2005-9-5 11:36:12 得分:2
?


学习.....
Top
回复人:kasad() ( 一级(初级)) 信誉:100 2005-9-5 12:27:05 得分:0
?


to
wanguodu(足文字D):可能我记错了,这个是去年的问题
如果改成:char str 哪个小?为什么?
Top
回复人:dhy311(好好学习,天天向上) ( 三级(初级)) 信誉:99 2005-9-5 12:27:05 得分:5
?


pc上面是1,powerpc上面是0(vc6.0,windowsxp),
pc上面是:100, 100, 001 ( 001100100 = 100 ) ,低位放在低内存
powerpc上面是:011,001,000(01100100 = 100 ),高位放前面(codewarrior + macosx)


powerpc上面运行结果是:0,
pc上面运行结果是1
Top
回复人:xxyifan(一帆) ( 一级(初级)) 信誉:100 2005-9-5 12:46:13 得分:2
?


华为近年来已经不行了,大家就不要争着去了
Top
回复人:wanguodu(足文字D) ( 一级(初级)) 信誉:100 2005-9-5 13:20:56 得分:0
?


struct name1{
char str;
short x;
int num;
}


struct name2{
char str;
int num;
short x;
}


sizeof(struct name1)=8,sizeof(struct name2)=12--due to natural alignment of fields and structure itself, hehe.


Top
回复人:packe_peng_520() ( 一级(初级)) 信誉:100 2005-9-5 14:00:40 得分:5
?


樓上說的不對,改成char str也是一樣的,結構都占八個字節
Top
回复人:wanguodu(足文字D) ( 一级(初级)) 信誉:100 2005-9-5 14:13:10 得分:0
?


to packe_peng_520:
在第二个结构中,为保证num按四个字节对齐,char后必须留出3字节的空间;同时为保证整个结构的自然对齐(这里是4字节对齐),在x后还要补齐2个字节,这样就是12字节。
Top
回复人:kasad() ( 一级(初级)) 信誉:100 2005-9-5 14:28:39 得分:0
?


to wanguodu(足文字D) :
你是增加了short 类型 ,改变了short类型的位置才有变化,但如果只是char 和int 类型的话,无论谁前谁后都是8字节
Top
回复人:wanguodu(足文字D) ( 一级(初级)) 信誉:100 2005-9-5 14:48:08 得分:0
?


to kasad:
喔,我不知咋的把结构看成三个字段了,哈哈。
Top
回复人:kasad() ( 一级(初级)) 信誉:100 2005-9-5 14:55:50 得分:0
?




^_^
Top
回复人:superwyf(++) ( 一级(初级)) 信誉:100 2005-9-5 15:22:48 得分:3
?


该成这样跑1下,可以看清楚


#include <stdio.h>
void main()
{


int m=3;
int d =4;
union d
{
struct c
{
unsigned short s1:1;
unsigned short s2:1;
unsigned short s3:1;
unsigned short s4:1;
unsigned short s5:1;
unsigned short s6:1;
unsigned short s7:1;
unsigned short s8:1;
unsigned short s9:1;
}x;
char c;
}v;
v.c=100;
//v.x.m_c=5;
printf("s1 %d\n",v.x.s1);
printf("s2 %d\n",v.x.s2);
printf("s3 %d\n",v.x.s3);
printf("s4 %d\n",v.x.s4);
printf("s5 %d\n",v.x.s5);
printf("s6 %d\n",v.x.s6);
printf("s7 %d\n",v.x.s7);
printf("s8 %d\n",v.x.s8);
printf("s9 %d\n",v.x.s8);
}
Top
回复人:linestyle(linestyle) ( 二级(初级)) 信誉:100 2005-9-5 15:29:08 得分:0
?


高高低低:)
Top
回复人:moonfkypm(先锋) ( 一级(初级)) 信誉:100 2005-9-5 16:04:41 得分:0
?


高啊!
Top
回复人:phoenix96_2000(eXMe) ( 二级(初级)) 信誉:100 2005-9-5 16:44:17 得分:0
?


s3的值还依赖于最后一个没有设置的BIT,
如果先来个memset(&v,255,sizeof(v);
最后s3=5了


不过似乎未分配的堆栈数据都是0XCC,即11001100,
这样s3的最后一个bit就是0了
Top
回复人:zhuangxingzan(Helios) ( 一级(初级)) 信誉:100 2005-9-5 18:25:10 得分:0
?




一种情况:
class A
{
public:
A(){};
~A(){};
void Play(){};
private:
long m_lData;
};


class B :public A
{
public:
B(){};
~B(){};
void Play(){};
private:
long m_lData;
};


int _tmain(int argc, _TCHAR* argv[])
{
A *a = new B();
a->Play(); //进的A中的Play
((B*)a)->Play();//进的B中的Play()
return 0;
}


另外一种情况:
class A
{
public:
A(){};
~A(){};
virtual void Play(){};
private:
long m_lData;
};


class B :public A
{
public:
B(){};
~B(){};
void Play(){};
private:
long m_lData;
};


int _tmain(int argc, _TCHAR* argv[])
{
A *a = new B();
a->Play(); //进的B中的Play()
((B*)a)->Play();//进的B中的Play()
return 0;
}


Top
回复人:zhuangxingzan(Helios) ( 一级(初级)) 信誉:100 2005-9-5 18:26:08 得分:0
?


不好意思,发错了
Top
回复人:mostideal(三甲) ( 四级(中级)) 信誉:100 2005-9-5 19:30:14 得分:0
?


学习。
Top
回复人:duduhu(嘟嘟虎) ( 一级(初级)) 信誉:100 2005-9-5 22:41:15 得分:0
?


在BE中,一个字节的高4位放在低位,低4位放在高位,即对于100来说其存放顺序是 0100 0110;
而BE是先申请的放高位,那么就应该在后面补0,即010001100;
同样先申请的放高位的话,即s1对应010,s2对应001,s3对应100
所以结果为4


Top
回复人:boox(boox) ( 一级(初级)) 信誉:100 2005-9-5 22:48:34 得分:0
?


华为的题嘛。你要考虑它是搞网络的,自然要用网络字序了。网络字序都是Big Endian的。
所以是4
Top
回复人:thisworld(这个世界) ( 一级(初级)) 信誉:100 2005-9-5 22:58:59 得分:0
?


mark
Top
回复人:blackcrusoe(亚历山大) ( 一级(初级)) 信誉:100 2005-9-6 6:09:28 得分:0
?


在dev-c++4.9.9.0(gcc 3.3.1)下运行结果是5!!!
Top
回复人:lzl209(lzl) ( 一级(初级)) 信誉:100 2005-9-6 11:40:01 得分:0
?


看了前面这么多的人提到big-endian和little-endian,我觉得很奇怪。
这道题目应该与big-endian和little-endian没有直接关系吧,big-endian和little-endian
与字节顺序有关,这道题明显与位域的存储空间分配有关。如果位域从右到左分配(x86体系结构)应该是1(我应经验证过了),否则应该是0(没有条件)。麻烦有条件的兄弟验证一下,我觉得楼上的dhy311已经给出了最终的结果。
Top
回复人:brianlu(-) ( 三级(初级)) 信誉:100 2005-9-6 17:05:53 得分:0
?


up
Top
回复人:brianlu(-) ( 三级(初级)) 信誉:100 2005-9-6 17:26:18 得分:0
?


就是little endian 和 big endian的区别。
我以前在HP-UX上试过。
以前记得Alcatel的人问过我知不知道这两个概念。
考的就是看书细心不细心,有没有经常动手做过实验。书上明确写过排列方式根据OS不同会有不同的。


Top
回复人:lzl209(lzl) ( 一级(初级)) 信誉:100 2005-9-6 18:19:35 得分:0
?


你越说我越不明白了,little endian 和 big endian好像也与操作系统
没关系吧,应该与计算机的体系结构有关。而且这道面试题跟不就不是考
字节顺序的,靠的应该是一个字节内存储空间的分配方向。
Top
回复人:yuanyou(元友) ( 二级(初级)) 信誉:100 2005-9-6 18:27:53 得分:0
?


学习!
Top
回复人:alicewdq(小白) ( 一级(初级)) 信誉:100 2005-9-6 19:47:45 得分:0
?


学习!学习!学习!
Top
回复人:LoveCreatesBeauty(爱产生美) ( 二级(初级)) 信誉:106 2005-9-6 23:05:49 得分:2
?


如果char是单字节,原题跟little-endian,big-endian是没有关系的。
Top
回复人:kasad() ( 一级(初级)) 信誉:100 2005-9-7 17:38:51 得分:0
?


谢谢 各位 :)
Top
回复人:ChenLiuqing(没有心的鸟^_^(★★★★★)) ( 一级(初级)) 信誉:100 2005-09-08 16:32:00 得分:0
?
mark
Top
回复人:heguosheng(何国胜) ( 一级(初级)) 信誉:100 2005-09-08 17:12:00 得分:0
?
自己总结一下:
1、原题跟little-endian,big-endian没有关系
2、原题跟位域的存储空间分配有关,到底是从低字节分配还是从高字节分配,从Dev C++和VC7.1上看,都是从低字节开始分配,并且连续分配,中间不空,不像谭的书那样会留空位
3、原题跟编译器有关,编译器在未用堆栈空间的默认值分配上有所不同,Dev C++未用空间分配为
01110111b,VC7.1下为11001100b,所以在Dev C++下的结果为5,在VC7.1下为1。


注:PC一般采用little-endian,即高高低低,但在网络传输上,一般采用big-endian,即高低低高,华为是做网络的,所以可能考虑big-endian模式,这样输出结果可能为4
Top


该问题已经结贴 ,得分记录: vc_feeling (5)、 Bobby136 (5)、 tongyongmc (5)、 ruiding (5)、 duduhu (5)、 zhouhuahai (5)、 phoenixsharp (5)、 wanguodu (5)、 elvispl (5)、 zpzs (5)、 luwy (5)、 wanguodu (3)、 shmilvy (5)、 shockwave_115 (5)、 na1ve (5)、 showwecumt (5)、 dhy311 (3)、 hansin (2)、 dhy311 (5)、 xxyifan (2)、 packe_peng_520 (5)、 superwyf (3)、 LoveCreatesBeauty (2)、


7.
主  题: 我的一个面试题
作  者: fxh010101 (啤酒瓶)
等  级:
信 誉 值: 100
所属论坛: C/C++ C++ 语言
问题点数: 20
回复次数: 13
发表时间: 2005-9-3 11:48:27




1 接口在C++中是如何体现的
2 有许函数的类中,为什么他的析构函数也是虚函数。
回复人:zhouhuahai(道号"虚无") ( 四级(中级)) 信誉:100 2005-9-3 12:32:10 得分:0
?


1.纯virtual函数实现抽象类
2.Let us suppose that a particular kind of enemy target is an enemy tank, which you model, naturally enough (see Item 35, but also see Item M33), as a publicly derived class of EnemyTarget. Because you are interested in the total number of enemy tanks as well as the total number of enemy targets, you'll pull the same trick with the derived class that you did with the base class:


class EnemyTank: public EnemyTarget {
public:
EnemyTank() { ++numTanks; }
EnemyTank(const EnemyTank& rhs)
: EnemyTarget(rhs)
{ ++numTanks; }
~EnemyTank() { --numTanks; }
static size_t numberOfTanks()
{ return numTanks; }
virtual bool destroy();
private:
static size_t numTanks; // object counter for tanks
};
Having now added this code to two different classes, you may be in a better position to appreciate Item M26's general solution to the problem.


Finally, let's assume that somewhere in your application, you dynamically create an EnemyTank object using new, which you later get rid of via delete:


EnemyTarget *targetPtr = new EnemyTank;
...
delete targetPtr;
Everything you've done so far seems completely kosher. Both classes undo in the destructor what they did in the constructor, and there's certainly nothing wrong with your application, in which you were careful to use delete after you were done with the object you conjured up with new. Nevertheless, there is something very troubling here. Your program's behavior is undefined — you have no way of knowing what will happen.


The °C++ language standard is unusually clear on this topic. When you try to delete a derived class object through a base class pointer and the base class has a nonvirtual destructor (as EnemyTarget does), the results are undefined. That means compilers may generate code to do whatever they like: reformat your disk, send suggestive mail to your boss, fax source code to your competitors, whatever. (What often happens at runtime is that the derived class's destructor is never called. In this example, that would mean your count of EnemyTanks would not be adjusted when targetPtr was deleted. Your count of enemy tanks would thus be wrong, a rather disturbing prospect to combatants dependent on accurate battlefield information.)




Top
回复人:Riddick2046(神为) ( 一级(初级)) 信誉:100 2005-9-3 13:10:19 得分:0
?


1 利用基类放纯虚函数, 让派生类 一定要去实现该方法. 其基类好比一个抽象类了.




2 当有 A *a=new B 时 ( A 基类 ,B派生类) 当delete a 时 是无法删去 A那部分内存.


只有用虚析构 才能完成先删 B 部分 再删A部分.
Top
回复人:mituzhishi(慎独) ( 二级(初级)) 信誉:100 2005-9-3 13:25:38 得分:0
?


1.有纯虚函数的类相当于接口。


2.虚函数是为了用父类析构时还能调用子类的析构函数,


这样子析构得更彻底,否则只调用父类的析构函数。
Top
回复人:wzjall() ( 一级(初级)) 信誉:100 2005-9-4 9:04:54 得分:0
?


条款14: 确定基类有虚析构函数


有时,一个类想跟踪它有多少个对象存在。一个简单的方法是创建一个静态类成员来统计对象的个数。这个成员被初始化为0,在构造函数里加1,析构函数里减1。(条款m26里说明了如何把这种方法封装起来以便很容易地添加到任何类中,“my article on counting objects”提供了对这个技术的另外一些改进)


设想在一个军事应用程序里,有一个表示敌人目标的类:


class enemytarget {
public:
enemytarget() { ++numtargets; }
enemytarget(const enemytarget&) { ++numtargets; }
~enemytarget() { --numtargets; }


static size_t numberoftargets()
{ return numtargets; }


virtual bool destroy(); // 摧毁enemytarget对象后
// 返回成功


private:
static size_t numtargets; // 对象计数器
};


// 类的静态成员要在类外定义;
// 缺省初始化为0
size_t enemytarget::numtargets;


这个类不会为你赢得一份政府防御合同,它离国防部的要求相差太远了,但它足以满足我们这儿说明问题的需要。


敌人的坦克是一种特殊的敌人目标,所以会很自然地想到将它抽象为一个以公有继承方式从enemytarget派生出来的类(参见条款35及m33)。因为不但要关心敌人目标的总数,也要关心敌人坦克的总数,所以和基类一样,在派生类里也采用了上面提到的同样的技巧:


class enemytank: public enemytarget {
public:
enemytank() { ++numtanks; }


enemytank(const enemytank& rhs)
: enemytarget(rhs)
{ ++numtanks; }


~enemytank() { --numtanks; }


static size_t numberoftanks()
{ return numtanks; }


virtual bool destroy();


private:
static size_t numtanks; // 坦克对象计数器
};


(写完以上两个类的代码后,你就更能够理解条款m26对这个问题的通用解决方案了。)


最后,假设程序的其他某处用new动态创建了一个enemytank对象,然后用delete删除掉:


enemytarget *targetptr = new enemytank;


...


delete targetptr;


到此为止所做的一切好象都很正常:两个类在析构函数里都对构造函数所做的操作进行了清除;应用程序也显然没有错误,用new生成的对象在最后也用delete删除了。然而这里却有很大的问题。程序的行为是不可预测的——无法知道将会发生什么。


c+ +语言标准关于这个问题的阐述非常清楚:当通过基类的指针去删除派生类的对象,而基类又没有虚析构函数时,结果将是不可确定的。这意味着编译器生成的代码将会做任何它喜欢的事:重新格式化你的硬盘,给你的老板发电子邮件,把你的程序源代码传真给你的对手,无论什么事都可能发生。(实际运行时经常发生的是,派生类的析构函数永远不会被调用。在本例中,这意味着当targetptr 删除时,enemytank的数量值不会改变,那么,敌人坦克的数量就是错的,这对需要高度依赖精确信息的部队来说,会造成什么后果?)


为了避免这个问题,只需要使enemytarget的析构函数为virtual。声明析构函数为虚就会带来你所希望的运行良好的行为:对象内存释放时,enemytank和enemytarget的析构函数都会被调用。


和绝大部分基类一样,现在enemytarget类包含一个虚函数。虚函数的目的是让派生类去定制自己的行为(见条款36),所以几乎所有的基类都包含虚函数。


如果某个类不包含虚函数,那一般是表示它将不作为一个基类来使用。当一个类不准备作为基类使用时,使析构函数为虚一般是个坏主意。请看下面的例子,这个例子基于arm(“the annotated c++ reference manual”)一书的一个专题讨论。


// 一个表示2d点的类
class point {
public:
point(short int xcoord, short int ycoord);
~point();


private:
short int x, y;
};


如果一个short int占16位,一个point对象将刚好适合放进一个32位的寄存器中。另外,一个point对象可以作为一个32位的数据传给用c或fortran等其他语言写的函数中。但如果point的析构函数为虚,情况就会改变。


实现虚函数需要对象附带一些额外信息,以使对象在运行时可以确定该调用哪个虚函数。对大多数编译器来说,这个额外信息的具体形式是一个称为vptr(虚函数表指针)的指针。vptr指向的是一个称为vtbl(虚函数表)的函数指针数组。每个有虚函数的类都附带有一个vtbl。当对一个对象的某个虚函数进行请求调用时,实际被调用的函数是根据指向vtbl的vptr在vtbl里找到相应的函数指针来确定的。


虚函数实现的细节不重要(当然,如果你感兴趣,可以阅读条款m24),重要的是,如果point类包含一个虚函数,它的对象的体积将不知不觉地翻番,从2个16位的short变成了2个16 位的short加上一个32位的vptr!point对象再也不能放到一个32位寄存器中去了。而且,c++中的point对象看起来再也不具有和其他语言如c中声明的那样相同的结构了,因为这些语言里没有vptr。所以,用其他语言写的函数来传递point也不再可能了,除非专门去为它们设计vptr,而这本身是实现的细节,会导致代码无法移植。


所以基本的一条是,无故的声明虚析构函数和永远不去声明一样是错误的。实际上,很多人这样总结:当且仅当类里包含至少一个虚函数的时候才去声明虚析构函数。


这是一个很好的准则,大多数情况都适用。但不幸的是,当类里没有虚函数的时候,也会带来非虚析构函数问题。例如,条款13里有个实现用户自定义数组下标上下限的类模板。假设你(不顾条款m33的建议)决定写一个派生类模板来表示某种可以命名的数组(即每个数组有一个名字)。


template<class t> // 基类模板
class array { // (来自条款13)
public:
array(int lowbound, int highbound);
~array();


private:
vector<t> data;
size_t size;
int lbound, hbound;
};


template<class t>
class namedarray: public array<t> {
public:
namedarray(int lowbound, int highbound, const string& name);
...


private:
string arrayname;
};


如果在应用程序的某个地方你将指向namedarray类型的指针转换成了array类型的指针,然后用delete来删除array指针,那你就会立即掉进“不确定行为”的陷阱中。


namedarray<int> *pna =
new namedarray<int>(10, 20, "impending doom");


array<int> *pa;


...




pa = pna; // namedarray<int>* -> array<int>*


...


delete pa; // 不确定! 实际中,pa->arrayname
// 会造成泄漏,因为*pa的namedarray
// 永远不会被删除




现实中,这种情形出现得比你想象的要频繁。让一个现有的类做些什么事,然后从它派生一个类做和它相同的事,再加上一些特殊的功能,这在现实中不是不常见。 namedarray没有重定义array的任何行为——它继承了array的所有功能而没有进行任何修改——它只是增加了一些额外的功能。但非虚析构函数的问题依然存在(还有其他问题,参见m33)


最后,值得指出的是,在某些类里声明纯虚析构函数很方便。纯虚函数将产生抽象类——不能实例化的类(即不能创建此类型的对象)。有些时候,你想使一个类成为抽象类,但刚好又没有任何纯虚函数。怎么办?因为抽象类是准备被用做基类的,基类必须要有一个虚析构函数,纯虚函数会产生抽象类,所以方法很简单:在想要成为抽象类的类里声明一个纯虚析构函数。


这里是一个例子:


class awov { // awov = "abstract w/o
// virtuals"
public:
virtual ~awov() = 0; // 声明一个纯虚析构函数


};


这个类有一个纯虚函数,所以它是抽象的,而且它有一个虚析构函数,所以不会产生析构函数问题。但这里还有一件事:必须提供纯虚析构函数的定义:


awov::~awov() {} // 纯虚析构函数的定义


这个定义是必需的,因为虚析构函数工作的方式是:最底层的派生类的析构函数最先被调用,然后各个基类的析构函数被调用。这就是说,即使是抽象类,编译器也要产生对~awov的调用,所以要保证为它提供函数体。如果不这么做,链接器就会检测出来,最后还是得回去把它添上。


可以在函数里做任何事,但正如上面的例子一样,什么事都不做也不是不常见。如果是这种情况,那很自然地会想到将析构函数声明为内联函数,从而避免对一个空函数的调用所产生的开销。这是一个很好的方法,但有一件事要清楚。


因为析构函数为虚,它的地址必须进入到类的vtbl(见条款m24)。但内联函数不是作为独立的函数存在的(这就是“内联”的意思),所以必须用特殊的方法得到它们的地址。条款33对此做了全面的介绍,其基本点是:如果声明虚析构函数为inline,将会避免调用它们时产生的开销,但编译器还是必然会在什么地方产生一个此函数的拷贝。


Top
回复人:lyclowlevel(蓬蒿人) ( 二级(初级)) 信誉:100 2005-9-4 11:45:29 得分:0
?


呵呵,都被说光了。
Top
回复人:heguosheng(何国胜) ( 一级(初级)) 信誉:100 2005-9-4 15:23:55 得分:0
?


mark
Top
回复人:lovesnow1314(流浪) ( 一级(初级)) 信誉:100 2005-09-05 01:11:00 得分:0
?
mark
Top
回复人:purplesunshine((紫色阳光)) ( 一级(初级)) 信誉:100 2005-09-05 08:41:00 得分:0
?
mark 一下
Top
回复人:lineuser(蓝冰) ( 一级(初级)) 信誉:100 2005-09-05 09:33:00 得分:0
?
学习学习
Top
回复人:adventure007(adventure) ( 一级(初级)) 信誉:100 2005-09-05 10:03:00 得分:0
?
学习学习
Top
回复人:xxyifan(一帆) ( 一级(初级)) 信誉:100 2005-09-05 10:25:00 得分:0
?
刚知道
Top
回复人:ChenLiuqing(没有心的鸟^_^(★★★★★)) ( 一级(初级)) 信誉:100 2005-09-05 10:31:00 得分:0
?
学习!
Top
回复人:blackcrusoe(亚历山大) ( 一级(初级)) 信誉:100 2005-09-06 06:07:00 得分:0
?
句柄类,代理类,抽象类都可以体检接口啊。




8.
主  题: SAP的面试题,大家试试看吧
作  者: pinkie191 (flying dog)
等  级:
信 誉 值: 100
所属论坛: C/C++ C++ 语言
问题点数: 80
回复次数: 44
发表时间: 2005-8-30 20:29:56




1.Below is usual way we find one element in an array:
const int *find1(const int* array, int n, int x)
{
const int* p = array;
for(int i = 0; i < n; i++)
{
if(*p == x)
{
return p;
}
++p;
}
return 0;
}
In this case we have to bear the knowledge of value type "int", the size of
array,
even the existence of an array. Would you re-write it using template to elim
inate all
these dependencies?
2. Assume you have a class like
class erp
{
HR* m_hr;
FI* m_fi;
public:
erp()
{
m_hr = new HR();
m_fi = new FI();
}
~erp()
{
}
};
if "new FI()" failed in the constructor, how can you detect this problem and
release the
properly allocated member pointer m_hr?
3. Check the class and variable definition below:
#include <iostream>
#include <complex>
using namespace std;
class Base
{
public:
Base() { cout<<"Base-ctor"<<endl; }
~Base() { cout<<"Base-dtor"<<endl; }
virtual void f(int) { cout<<"Base::f(int)"<<endl; }
virtual void f(double) {cout<<"Base::f(double)"<<endl; }
virtual void g(int i = 10) {cout<<"Base::g()"<<i<<endl; }
};
class Derived: public Base
{
public:
Derived() { cout<<"Derived-ctor"<<endl; }
~Derived() { cout<<"Derived-dtor"<<endl; }
void f(complex<double>) { cout<<"Derived::f(complex)"<<endl; }
virtual void g(int i = 20) {cout<<"Derived::g()"<<i<<endl; }
};
Base b;
Derived d;
Base* pb = new Derived;
Select the correct one from the four choices:
Cout<<sizeof(Base)<<endl;
A. 4 B.32 C.20 D.Platform-dependent
Cout<<sizeof(Base)<<endl;
A. 4 B.8 C.36 D.Platform-dependent
pb->f(1.0);
A.Derived::f(complex) B.Base::f(double)
pb->g();
A.Base::g() 10 B.Base::g() 20
C.Derived::g() 10 D.Derived::g() 20
4.Implement the simplest singleton pattern(initialize if if necessary).
5.Name three sort algorithms you are familiar with. Write out the correct or
der by the
average time complexity.
6.Write code to sort a duplex direction linklist. The node T has overridden
the comparision operators


回复人:xiaocai0001(萧筱雨) ( 五级(中级)) 信誉:100 2005-8-30 20:31:59 得分:0
?


晕~~


全都是English,看得好累~~~
Top
回复人:foochow(恰似你的温柔) ( 一星(中级)) 信誉:100 2005-8-30 20:43:16 得分:0
?


汗,先占个位...
Top
回复人:pinkie191(flying dog) ( 一级(初级)) 信誉:100 2005-8-30 20:43:24 得分:0
?


英语在眼前是月来月重要的了,哥们!加紧学习啊
1。如何用摸板重新编写函数
2。如果new FI()" 失败,如何捕获,第二如何给指针m_hr分配内存
3。比较清楚了已经。
4。写出最简单的单实例模式
5。三个排序算法,给出时间复杂度
6。双向连表排序,接点重载了比较运算符
Top
回复人:llf_hust() ( 五级(中级)) 信誉:100 2005-8-30 20:44:56 得分:0
?


study
Top
回复人:xiaocai0001(萧筱雨) ( 五级(中级)) 信誉:100 2005-8-30 20:47:55 得分:0
?


呵呵~~
只怪英语六级过得太早,大二上就给过了,后面几年都没了学英语的动力了.


现在又要拿起来学啊~~


关注中~~~
Top
回复人:xiaocai0001(萧筱雨) ( 五级(中级)) 信誉:100 2005-8-30 21:08:08 得分:0
?


呵呵
终于看完了~~


补充一下,楼主的第二题意说明得不太准确.


第二题是说 如果类构造函数里面的成员new FI()失败了,你怎样检测到这种错误,并且正确的释放掉
m_hr指针的空间


再有第三题


Cout<<sizeof(Base)<<endl;
A. 4 B.32 C.20 D.Platform-dependent
Cout<<sizeof(Base)<<endl;
A. 4 B.8 C.36 D.Platform-dependent


第二个我认为是
cout<<sizeof(Derived)<<endl;
A. 4 B.8 C.36 D.Platform-dependent
应该是楼主的失误吧~~~
Top
回复人:pinkie191(flying dog) ( 一级(初级)) 信誉:100 2005-8-30 21:11:01 得分:0
?


是的,你说的 没错
Top
回复人:jixingzhong(瞌睡虫(既然选择了远方,那就只有风雨兼程了!!)) ( 五级(中级)) 信誉:101 2005-8-30 21:22:19 得分:0
?


Select the correct one from the four choices:
Cout<<sizeof(Base)<<endl; // ?
A. 4 B.32 C.20 D.Platform-dependent
Cout<<sizeof(Base)<<endl; // B
A. 4 B.8 C.36 D.Platform-dependent
pb->f(1.0); // B
A.Derived::f(complex) B.Base::f(double)
pb->g(); // B
A.Base::g() 10 B.Base::g() 20
C.Derived::g() 10 D.Derived::g() 20


具体的结果测试一下就知道了,这个是我做的 ,错了别笑 ~ 呵呵


Top
回复人:qhfu(崩溃) ( 一星(中级)) 信誉:105 2005-8-30 21:41:12 得分:0
?


试着做一下!
1,
template<class T,int size>
const T *find1(const T* array, int x)
{
const T* p = array;
for(int i = 0; i < size; i++)
{
if(*p == x)
{
return p;
}
++p;
}
return 0;
}
2,
erp()
{
try
{
m_hr = new HR();
m_fi = new FI();
}
catch(bad_alloc& e)
{
cout << ba.what( ) << endl;
delete m_hr;
delete m_fi;
}
}


3,
Cout<<sizeof(Base)<<endl;
A. 4
pb->f(1.0);
A.Derived::f(complex)
pb->g();
C.Derived::g() 10
4
class SingleTon
{
public:
static SingleTon* getInstance()
{
if (instance == 0)
{
instance = new SingleTon;
}
return instance;
}
private:
SingleTon()
{
cout<<"SingleTon()"<<endl;
}
SingleTon(const SingleTon&);
SingleTon& operator=(const SingleTon&);
static SingleTon * instance;
};


SingleTon* SingleTon::instance = 0;
5,
counting sort O(n) < quicksort O(nlgn) < insert sortO(n^2);
6,......用冒泡吧!


大概做了一下,呵呵!
Top
回复人:xiaocai0001(萧筱雨) ( 五级(中级)) 信誉:100 2005-8-30 21:45:30 得分:0
?


TO: qhfu(崩溃)
try
{
m_hr = new HR();
m_fi = new FI();
}
catch(bad_alloc& e)
{
cout << ba.what( ) << endl;
delete m_hr;
delete m_fi;
//上面这两个delete有问题吧,值得商榷
//如果new FI()失败了, 则m_fi应该没有得到空间, 何来delete m_fi;
//再者, new HR()也可能失败了,被catch捕捉到了, 那么连delete m_hr;也值得怀疑了~~~


}


Top
回复人:qhfu(崩溃) ( 一星(中级)) 信誉:105 2005-8-30 21:47:29 得分:0
?


jixingzhong(瞌睡虫(既然选择了远方,那就只有风雨兼程了!!))
我们做的答案都不一样啊
pb->f(1.0); // B
A.Derived::f(complex) B.Base::f(double)
  觉得应该是A吧, 理由是:Base中的f都被覆盖了,就是在 Derived中都看不到了。 所以动态邦定到Derived::f(complex),这个上, 觉得呢?


pb->g(); // B
A.Base::g() 10 B.Base::g() 20
C.Derived::g() 10 D.Derived::g() 20


  觉得是 c 因为缺省参数是在编译期邦定的,所以我觉得是 c。 


讨论一下 ,呵呵! 


Top
回复人:qhfu(崩溃) ( 一星(中级)) 信誉:105 2005-8-30 21:49:46 得分:0
?


to:xiaocai0001(萧筱雨)
应该是你说的这样!  呵呵我只是偷懒。觉得如果写两个catch有点傻!   而且delete一个 0指针反正没有伤害,题目上又说是下面那个出现异常  所以 就这样写了。
Top
回复人:xiaocai0001(萧筱雨) ( 五级(中级)) 信誉:100 2005-8-30 21:51:43 得分:0
?


本人不才,在机器上试了一下
VC6.0 + Windows 2000
结果如下:
sizeof(Base) = 4
sizeof(Derived) = 4
pb->f(1.0);
Base::f(double)
pb->g();
Derived::g()10
Top
回复人:xiaocai0001(萧筱雨) ( 五级(中级)) 信誉:100 2005-8-30 21:54:15 得分:0
?


呵呵~~
是我多虑了
原来在C语言里用free()的时候,如果参数是NULL的话,会出现非法.
所以以为 delete 也会这样
刚试了一下,没问题。所以那样写没有什么问题~~~
学习~~
Top
回复人:xiaocai0001(萧筱雨) ( 五级(中级)) 信誉:100 2005-8-30 21:56:15 得分:0
?


不过上次在CSDN看到有人说
内存分配失败后抛出异常,而指针并不会置空。如果真的是这样,那就需要考虑考虑了~~


Top
回复人:qhfu(崩溃) ( 一星(中级)) 信誉:105 2005-8-30 22:00:01 得分:0
?


我也不知道,说不定确实真的写错了,变通办法当然是有的,就是在初始化表中先置零,不过又是很傻的作法!  
  前面一个
pb->f(1.0);
Base::f(double)
我倒有点不理解! 看来还有待加强阿! 我记得好像是会被覆盖掉的,,不过事实是我错了,,请高手讲解!
Top
回复人:snowbirdfly(胡晋) ( 三级(初级)) 信誉:100 2005-8-30 22:20:23 得分:0
?


学习了~


Top
回复人:Ibanez119() ( 一级(初级)) 信誉:100 2005-8-30 22:35:01 得分:0
?


mark
Top
回复人:foochow(恰似你的温柔) ( 一星(中级)) 信誉:100 2005-8-30 23:07:38 得分:0
?


erp():m_hr(0),m_fi(0)
{
try
{
m_hr = new HR();
m_fi = new FI();
}
catch(...)
{
delete m_hr;
delete m_fi;
throw;
}
}
//构造期间抛出exception,析构函数是不会被调用的...
Top
回复人:foochow(恰似你的温柔) ( 一星(中级)) 信誉:100 2005-8-31 0:03:22 得分:0
?


pb->g();
Derived::g()10
虚函数是动态绑定而缺省参数值是静态绑定.....
..................
Base* pb = new Derived;
pb->f(1.0);
Base::f(double)
....
如果一个派生类的函数与它的一个基类函数参数不同,而函数名相同且基类的这个函数是virtual,那么基类的这个函数将被隐式继承到派生类的vtable中.这时如果用基类指针实现多态并调用该函数,则这个派生类的函数将会被隐藏.....


..........


Top
回复人:yangjundeng(天下无双) ( 一级(初级)) 信誉:100 2005-8-31 9:00:36 得分:0
?


4题:
/*----------------------------------------------------------------------
(c)2005 C2217 Studio
Module:Singleton.h
Purpose:Implement singleton pattern by template
History:
8/29/2005Create
----------------------------------------------------------------------*/
#pragma once


#include <memory>
using namespace std;




namespace C2217
{
namespace Pattern
{
template <class T>
class Singleton
{
public:
static inline T* instance();


private:
Singleton(void){}
~Singleton(void){}
Singleton(const Singleton&){}
Singleton & operator= (const Singleton &){}


static auto_ptr<T> _instance;
};


template <class T>
auto_ptr<T> Singleton<T>::_instance;


template <class T>
inline T* Singleton<T>::instance()
{
if( 0 == _instance.get() )
{
_instance.reset ( new T);
}
return _instance.get();
}


//Class that will implement the singleton mode,
//must use the macro in it's delare file
#define DECLARE_SINGLETON_CLASS( type ) \
friend class auto_ptr< type >;\
friend class Singleton< type >;
}
}


使用方法:
#pragma once


#include <string>
#include <vector>
using namespace std;


#include "singleton.h"
using namespace C2217::Pattern;


class User
{
public:
string _name;


DECLARE_SINGLETON_CLASS


public:
User(void){std::cout << "Default Create User" << std::endl;}
User(string name):_name(name){std::cout << "Parameters Create User" << std::endl;}


virtual ~User(void);
};


typedef Singleton<User> userSingle;


int _tmain(int argc, _TCHAR* argv[])
{
userSingle::instance()->_name = "dyj057";
}


如果需要多线程安全的访问,需要加保护.


Top
回复人:antijpn(antijpn) ( 一星(中级)) 信誉:100 2005-8-31 9:07:27 得分:0
?


有C++的题目,转C++
Top
回复人:junguo(junguo) ( 五级(中级)) 信誉:105 2005-8-31 10:37:11 得分:0
?


1,template<typename T,int size>
const T *find1(T (&array)[size],T x)
{
const T* p = array;
for(int i = 0; i < size; i++)
{
if(*p == x)
{
return p;
}
++p;
}
return 0;
}
2,
class erp
{
auto_ptr<HR>m_hr;
auto_ptr<FI>m_fi;
public:
erp()
: m_hr(new HR()),m_fi(new FI)
{


}
~erp()
{
}
};
Top
回复人:ningzhiyu(凝滞雨) ( 四级(中级)) 信誉:100 2005-8-31 10:54:34 得分:0
?


学习
Top
回复人:heguosheng(何国胜) ( 一级(初级)) 信誉:100 2005-8-31 12:39:21 得分:0
?


up
Top
回复人:ixw() ( 一级(初级)) 信誉:100 2005-8-31 14:19:43 得分:0
?


mark
Top
回复人:karlfly(flykarl) ( 一级(初级)) 信誉:100 2005-8-31 15:44:30 得分:0
?


高手啊
Top
回复人:UnrealImagecoffee(幻影的咖啡) ( 二级(初级)) 信誉:100 2005-8-31 16:40:49 得分:0
?


战位
Top
回复人:SammyLan(没有窍门,只有努力.LOVE 33 4 Ever ) ( 二级(初级)) 信誉:98 2005-8-31 17:34:40 得分:0
?


MARK


Top
回复人:lyclowlevel(蓬蒿人) ( 二级(初级)) 信誉:100 2005-8-31 18:53:39 得分:0
?


问一下new如果失败会抛出异常吗?如果会,抛出什么类型的异常?
Top
回复人:yangjundeng(天下无双) ( 一级(初级)) 信誉:100 2005-9-1 17:38:27 得分:0
?


bad_alloc
Top
回复人:hannergsx(喊) ( 一级(初级)) 信誉:100 2005-9-1 17:55:38 得分:0
?


up
Top
回复人:lyclowlevel(蓬蒿人) ( 二级(初级)) 信誉:100 2005-9-1 18:10:50 得分:0
?


谢楼上的解答。


qhfu(崩溃)
===========
我个人觉得你的做法是不行的。应该象 foochow(恰似你的温柔)
那样,将异常重新抛出。


Top
回复人:SammyLan(没有窍门,只有努力.LOVE 33 4 Ever ) ( 二级(初级)) 信誉:98 2005-9-1 18:14:18 得分:0
?


MARK


Top
回复人:Leaveye(~枝)(一点不了解系统,也懒得实际量测性能) ( 五级(中级)) 信誉:100 2005-9-1 23:42:22 得分:0
?


Base::f(double)
Derived::f(complex<double>)


关键在于调用 f(1.0) 的参数类型是一个浮点数。


看起来函数被继承后重新实现,其实只是在子类中,重载了这个函数f而已。
子类中有两个f,一个接收参数double,一个接收参数complex,double是继承自基类的。
Top
回复人:qhfu(崩溃) ( 一星(中级)) 信誉:105 2005-9-1 23:56:56 得分:0
?


谢楼上的解答。


qhfu(崩溃)
===========
我个人觉得你的做法是不行的。应该象 foochow(恰似你的温柔)
那样,将异常重新抛出。
========================================================
为什么不行,能不能给个理由?


==============================================================================
Base::f(double)
Derived::f(complex<double>)


关键在于调用 f(1.0) 的参数类型是一个浮点数。


看起来函数被继承后重新实现,其实只是在子类中,重载了这个函数f而已。
子类中有两个f,一个接收参数double,一个接收参数complex,double是继承自基类的。
==============================================================================


其实这里的关键在于题目的指针是Base* ,所以他会帮定到f(double).


Top
回复人:LoveCreatesBeauty(爱产生美) ( 二级(初级)) 信誉:106 2005-9-2 0:05:27 得分:0
?


up
Top
回复人:lyclowlevel(蓬蒿人) ( 二级(初级)) 信誉:100 2005-9-2 14:40:47 得分:0
?


qhfu(崩溃) ( )
-----------------------------------------
我给个例子:
#include<iostream>
using namespace std;
class MyClass
{
public:
void *operator new(size_t)
{
bad_alloc temp;
throw temp;
}
void operator delete(void *){}
};
class TestClass
{
public:
int *a;
MyClass *b;
public:
TestClass()
{
try
{
a=new int(0);
b=new MyClass;
}
catch(bad_alloc)
{
delete a;
delete b;
//throw;
}
}
void func()
{
*a=1;
}
};
void main()
{
TestClass* pTC=new TestClass;
pTC->func();
cout<<*(pTC->a);
}
如果没有重新抛出异常,那么main中的pTC的构造被认为是成功的,也就是pTC->func();是OK的。
但,这就是问题了。因为,pTC指向的对象中的a指向的那片空间在构造函数中已经被delete了。


还有一点,本来我以为在构造函数中重新抛出异常,编译时会在pTC->func();这一句报错,
但是没有,只是不能运行而已。


我个人觉得你的做法应该是存在bug的。
Top
回复人:bugebear3() ( 二级(初级)) 信誉:100 2005-9-2 15:18:55 得分:0
?


C++有太多的东西似是而非呀
Top
回复人:bootblack(擦鞋匠) ( 二级(初级)) 信誉:100 2005-9-2 17:53:36 得分:0
?


作个记号先
Top
回复人:shine2000(勇敢的心) ( 一级(初级)) 信誉:100 2005-09-02 23:19:00 得分:0
?
mark
Top
回复人:williamx(WILL) ( 二级(初级)) 信誉:98 2005-09-03 01:06:00 得分:0
?
SAP 是啥?
Top
回复人:yuanyou(元友) ( 二级(初级)) 信誉:100 2005-09-03 09:04:00 得分:0
?
学习
Top
回复人:liushuang108(小T) ( 一级(初级)) 信誉:100 2005-09-03 09:29:00 得分:0
?
学习了
Top


9.
主  题: 两道字符串的面试题?
作  者: vliuyan0435 ()
等  级:
信 誉 值: 100
所属论坛: C/C++ C++ 语言
问题点数: 50
回复次数: 14
发表时间: 2005-08-29 23:29:41


1.对多个字符串str,如果遇见空格或者标点符号,则将后面的字符串放到前面,也就是做一个顺序倒排.
eg:"I am a student."处理后变做"student a am I".
然后将倒排后的结果放入str中.
2.编写一个简单的对字符串的加密解密程序.
回复人:vliuyan0435() ( 一级(初级)) 信誉:100 2005-08-29 23:38:00 得分:0
?
第1题
ctype.h中有这样针对字符的宏
#define isspace(c)(c=32),判断是否该字符是否是空格
#define isgraph(c),判断字符是否是图形字符,也就是标点符号了.
我想改一下就可以对str进行相同的判断.具体应该怎么改呢?


顺序倒排问题
对str从头开始进行遍历,发现空格或者标点符号就将其后的字符放在最前面.
对字符串好说,但是对多个字符串我就不知道怎么做了


最后用一个strcpy就可以把放结果放入str了.


第2题我就完全不知道了


我对C还是很菜的,望指教!
Top
回复人:Temp0x01() ( 一级(初级)) 信誉:100 2005-08-30 00:10:00 得分:0
?
到序用栈,简单加密可直接对每个字符加一个常量.
Top
回复人:qhfu(崩溃) ( 一星(中级)) 信誉:105 2005-08-30 00:13:00 得分:0
?
1,其实很简单,读字符串,读到空格,把前面的子串放入容器中, 然后反向输出就好了。
注意问题:最后一个字串要特别处理。(c++的方法)
2,可以通过随便什么方法生成一个密钥,也是一个字符串,长度和原来的一样。然后把每个字符的ASCII码相加 对 26或者52取余(看区不区分大小写),再 + 'a'.重新生成一个字符串。这是加密算法。
解密:就是还原出原来的字符串。
Top
回复人:K() ( 三级(初级)) 信誉:100 2005-08-30 00:50:00 得分:0
?
1.
char str[]="I am a student.";
cout<<str<<endl;
reverse(&str[0],&str[strlen(str)]) ;
cout<<str<<endl;
2.
char str[]="I am a student.";
for (int i=0;i<strlen(str);i++)
{
str[i]=str[i]+'a';
}/*加*/


for (int i=0;i<strlen(str);i++)
{
str[i]=str[i]-'a';
}//解
Top
回复人:jixingzhong(瞌睡虫(既然选择了远方,那就只有风雨兼程了!!)) ( 五级(中级)) 信誉:101 2005-08-30 08:29:00 得分:0
?
一个简单的恺撒加密程序 (恺撒加密是嘴尖但的加密方法了 ...程序给个思路,修改一下就是了..)


#include<iostream>
#include<fstream>
void main(void)
{
char strch,ch;
int i,x;
ifstream readfile;
ofstream writefile;
readfile.open("1.txt",ios::in | ios::nocreate);
if(!readfile)
{


cerr<<"cannot open thie file for input"<<endl;


exit(0); }


writefile.open("2.txt",ios::in | ios::nocreate);


if(!writefile)


{


cerr<<"cannot open the file for output"<<endl;


exit(0); }


while(!readfile.eof())


{


ch=readfile.get();


x=static_cast<int>(ch);


x=(x+3)%128;


strch=static_cast<char>(x);


writefile.put(strch);


}


}
Top
回复人:zhouhuahai(道号"虚无") ( 三级(初级)) 信誉:100 2005-08-30 09:06:00 得分:0
?
楼上的楼上所用的std::reverse不行吧?
请看清题目的意思再回答.
Top
回复人:conhacker(黎润) ( 一级(初级)) 信誉:100 2005-08-30 11:31:00 得分:0
?
int main(int argc, char* argv[])
{
string str1;
string str2;
char str[]="shi wo";
for(int i = 0; i<strlen(str)+1 ;i++)
{
if(str[i] > 65 && str[i]< 122 )
{
str2 = str2 + str[i] ;
}
else
{
str1 = str2 + " " + str1;
str2.erase();
}
}


cout<<endl<<str1<<endl;


//printf("Hello World!\n");
return 0;
}
Top
回复人:llf_hust() ( 五级(中级)) 信誉:100 2005-08-30 11:43:00 得分:0
?
if(str[i] >= 65 && str[i] <= 122 )
Top
回复人:foochow(恰似你的温柔) ( 一星(中级)) 信誉:100 2005-08-30 13:12:00 得分:0
?
//苯方法,随便写了下,不知道有没有错误...
#include<iostream>
#include<iterator>
#include<string>
#include<stack>
using namespace std;
int main()
{
string temp="GetKeyboardState SetKeyboardState,GetAsyncKeyState GetKeyState.";
string::iterator it=temp.begin();
string::iterator tt=it;
stack<string>Q;
string last;
while(1)
{
if(it==temp.end()){Q.push(string(tt,it));break;}
it++;
if(ispunct(*it)||isspace(*it))
{
if(ispunct(*it))
{
string::iterator its=it;
if(++its!=temp.end())
{
Q.push(string(tt,it));
string ps;
ps+=(*it);
Q.push(ps);
tt=it;
tt++;
}
else {
last+=*it;
Q.push(string(tt,it));
break;
}
}
else
{
Q.push(string(tt,it));
tt=it;
++tt;
}
}
}
string().swap(temp);
while(!Q.empty())
{
temp+=Q.top();
temp+=" ";
Q.pop();
}
temp+=last;
cout<<temp<<endl;
return 0;
}
Top
回复人:younggundog(炼狱中的游魂) ( 一级(初级)) 信誉:100 2005-08-30 13:44:00 得分:0
?
第一题:
顺序把标点,空格之间的子字串取出,压入栈,也把该子串后的空格或标点,压入栈!顺序弹出,拼接为目的串。
第二题:大家都说了!
Top
回复人:hncw13(13) ( 二级(初级)) 信誉:80 2005-08-30 14:21:00 得分:0
?
同意,qhfu(崩溃)


把一个由空格或者逗号分隔的字符串的每个子串都看作一个对象,这样读到空格就把子串放入容器中,然后reverse一下,就好了。
Top
回复人:vliuyan0435() ( 一级(初级)) 信誉:100 2005-08-31 02:15:00 得分:0
?
多谢以上的各位了
我自己大概写了一个,有点问题,大家帮忙看看!
void main()
{
int i,j;
char str[]="I am a student."
char str2[];
SeqStack(S);
InitStack(&S);
for(i=0;i<strlen(str);i++) //边历str,发现空格或者标点符号,则将空格
{ while(isspace(str)||isgraph(str)) 或者标点符号前面的字符压入栈
{ for(j=0;j<i;j++)
{
push(&S,str[j]); //问题?每次入栈都是从str的第一个字符开始,有重复
... ...处我想添加一个函数,每次入栈后便把str中入栈
} 的字符删除.应该怎么写?
} 或者对for(j=0;j<i;j++)进行修改?
while(!EmptyStack(&S))
{
str2[]=pop(&S);
}
}
strcpy(str,str2);
}


简单的字符串加解密原来是这样,呵呵~
恺撒加密程序?我对这方面真的不懂,能不能有朋友解释一下!谢谢了!
Top
回复人:y0z0(荒山之夜) ( 二级(初级)) 信誉:100 2005-08-31 04:43:00 得分:0
?
恺撒加密程序好像就是对所有字母进行“位移”,先定义一个距离,例如距离是3,则a变成d,b变成e,…,x变成a,y变成b,z变成c,这样;解密时按照当初设定的距离再还原就好了,这道题目我记得是我学C 语言时编的第二个小程序。当然这个算法只能对字母进行操作,也可以扩充到数字,但是字母和数字是分别加密的,解密时也要先判断是数字还是字母,然后分别解密;当然也可以使算法再复杂一点,将字母和数字混合。
Top
回复人:y0z0(荒山之夜) ( 二级(初级)) 信誉:100 2005-08-31 05:05:00 得分:0
?
/*从str的最后开始压栈,则退栈时就不用重新调整顺序*/
void main()
{
int i,j;
char str[]="I am a student.";
char *str2;
Stack S;
str2=(char*)malloc(sizeof(char)*(strlen(str)+1));
InitStack(&S);
for(i=strlen(str),j=0; i>=0; i--)/*从字符串尾的非0字符开始压栈*/
{
if(isspace(str[i])||isgraph(str[i]))
{
/*如果当前字符是标点或空格,将栈中字符串退栈给str2*/
while(!StackEmpty(&S))
{
str2[j]=pop(&S);
j++;
}
str2[j]=str[i];/*并将标点或空格赋给str2*/
j++;
}
else
{
/*否则将字符压入栈*/
push(&S,str[i]);
}
}
/*最后,将栈中剩余字符赋给str2*/
while(!StackEmpty(&S))
{
str2[j]=pop(&S);
j++;
}
str[j]='\0';/*str2收尾*/
/*Copy到原字符串,释放str2*/
strcpy(str,str2);
free(str2);
}




10.
主  题: 我的面试题,一个关于博弈算法的问题,谁能给出答案
作  者: viga_cheung (绝望中寻找希望)
等  级:
信 誉 值: 100
所属论坛: C/C++ 新手乐园
问题点数: 100
回复次数: 11
发表时间: 2005-8-25 16:33:19




一副扑克54张,张三、李四轮流抽牌,一次最多抽4张,最少抽1张,用c语言实现该算法:无论张三先抽还是后抽都能抽到最后一张牌,执行程序时,打印出张三能抽到最后一张牌的所有情况。
请高手们给出程序。
回复人:ahhy(蓝色海洋) ( 一级(初级)) 信誉:96 2005-8-25 16:39:02 得分:0
?


只要最后保证能有1,2,3,或者4张牌,是吧?
Top
回复人:xiaocai0001(萧筱雨) ( 四级(中级)) 信誉:100 2005-8-25 16:40:54 得分:0
?


逆向递推~~
张三:1-4
李四:5
张三:6-9
李四:10
张三:11-14
李四:15
张三:16-19
李四:20
张三:21-24
李四:25
张三:26-29
李四:30
张三:31-34
李四:35
张三:36-39
李四:40
张三:41-44
李四:45
张三:46-49
李四:50
张三:51-54


所以张三先抽4张则一定可以拿到最后一张


不存在张三无论先抽后抽都能拿到最后一张的说法~~~


Top
回复人:oo(为了名副其实,努力学习oo技术ing) ( 两星(中级)) 信誉:110 2005-8-25 16:51:03 得分:0
?


保持剩下的是5的倍数即可。
所以先抽的赢。
Top
回复人:yaoniming3500(腰子比猪大) ( 一级(初级)) 信誉:100 2005-8-25 16:52:48 得分:0
?


算法很简单,只要保证每次给李四留下(n+1)*i张就可以了,这里n=4,所以张三每次拿牌后给李四留5的倍数张牌就可以了。后拿是不可能的,不然就矛盾了。
Top
回复人:Bobby136(鄙视地球人!) ( 一级(初级)) 信誉:100 2005-8-26 9:38:06 得分:0
?


这个题目也需要用博弈算法,用牛刀杀鸡
Top
回复人:xugn_2003(一剑封喉) ( 一级(初级)) 信誉:100 2005-8-26 10:01:49 得分:0
?


有没有人给出一个具体的算法来?
Top
回复人:xxxdg(学习中) ( 二级(初级)) 信誉:100 2005-8-26 11:06:37 得分:0
?


一副扑克54张,张三、李四轮流抽牌,一次最多抽4张,最少抽1张,用c语言实现该算法:无论张三先抽还是后抽都能抽到最后一张牌,执行程序时,打印出张三能抽到最后一张牌的所有情况。
请高手们给出程序。


----------------------------------------------------------------


这个题目是一个伪题目,
根据对称原理,如果张三无论先抽还是后抽都能抽到最后一张牌,那么同样的,李四也是无论先抽还是后抽都能抽到最后一张牌。


对于本题,5是一个稳定结构,所以,先拿走四张的胜。
Top
回复人:brianlu(-) ( 三级(初级)) 信誉:100 2005-8-26 11:21:23 得分:0
?


up
Top
回复人:zoulie(珠峰菜鸟) ( 一级(初级)) 信誉:100 2005-8-26 11:26:23 得分:0
?


哪位高手写个算法出来让偶们菜鸟看看啊~~~
Top
回复人:antijpn(antijpn) ( 一星(中级)) 信誉:100 2005-8-26 19:47:36 得分:0
?


直接求代码,转新手乐园
Top
回复人:madoldman(疯癫叟) ( 一级(初级)) 信誉:100 2005-8-28 20:41:05 得分:0
?


同意三楼的,不存在


11.
5个高智商囚犯,分别按1-5号在装有100颗绿豆的麻袋面前站好,让他们按次序抓绿豆,规定每人至少要抓一颗,而抓得最多和最少的人将被处死,而且,他们之间不能交流,但在抓的时候,可以摸出剩下的豆子数量。问他们中谁的存活几率最大?
      提示:
      1,他们都是很聪明的人 !
      2,他们的原则是先求保命,再去多杀人 .
      3,100颗不必都分完 .
      4,若有重复的情况,则也算做是最大或最小的情况,一并处死
回复人:VivianSnow(Phoenix) ( 二级(初级)) 信誉:100 2005-8-18 18:52:52 得分:0
?


第三个人存活几率最大
Top
回复人:tufaqing() ( 一级(初级)) 信誉:100 2005-8-18 18:56:13 得分:0
?


最后一个人没有豆子抓了怎么办?
Top
回复人:VivianSnow(Phoenix) ( 二级(初级)) 信誉:100 2005-8-18 18:58:04 得分:0
?


题目可以理解成``必须保证后面每个人都可以抓到至少1粒豆子```


应该是第三个人``没错```
Top
回复人:xiaocai0001(萧筱雨) ( 三级(初级)) 信誉:100 2005-8-18 19:03:04 得分:0
?


早就发过了
怎么又出来了??
Top
回复人:xingbozy(3951263) ( 一级(初级)) 信誉:100 2005-8-18 20:17:08 得分:0
?


不可能最后一个没有抓的,每个人必须< 20粒,即为N粒,因为都是高智商,谁都怕死,不能大于平均数20,第二个能算出第一个,抓的肯定不能相同,所以剩下的如果是奇数,则最近的为N-2粒,如果为偶数则应为N-1粒,而第一位与第二位应该能算出第三位的结果(有种或两种),可是第四位为保全自身,只能选择前三位的平均数取整再减二,所以第二个人最坏,控制权最大,第三个人存活率应该最大!


这是本人自己的观点!请大家一起来讨论
Top
回复人:xingbozy(3951263) ( 一级(初级)) 信誉:100 2005-8-18 20:18:14 得分:0
?


有答案没?说答案吧?
Top
回复人:AncientHouse(小胖) ( 一级(初级)) 信誉:100 2005-8-18 20:39:41 得分:0
?


晕,好难的问题
Top
回复人:t_y(逝去的帆) ( 一级(初级)) 信誉:100 2005-8-18 20:43:55 得分:0
?


由于不可能都大于20,也不可能都小于20,第一个人抓20个就不会死了,除非大家想自杀,都抓20个
Top
回复人:xingbozy(3951263) ( 一级(初级)) 信誉:100 2005-8-18 20:48:40 得分:0
?


为什么不能小于20,第三个条件是100颗不必都分完!
Top
回复人:t_y(逝去的帆) ( 一级(初级)) 信誉:100 2005-8-18 20:48:58 得分:0
?


错了,不能都大于20,但是可以都小于20的,呵呵
Top
回复人:henan_lujun(地平风线) ( 二级(初级)) 信誉:100 2005-8-18 20:55:20 得分:0
?


有意思的,研究研究!
Top
回复人:xsp919(末末) ( 一级(初级)) 信誉:100 2005-8-19 9:32:45 得分:0
?


原本是第二个人或第三个人存活概率最大,但是大家都是最聪明的人,而且第五个是必死无疑,所以第五个肯定要拉一个垫背的,会抓一个中间数和其中的某一个一样。结果第一个最不容易死。
Top
回复人:tianhxk(c++<>_JAVA) ( 三级(初级)) 信誉:100 2005-08-19 12:30:00 得分:0
?
假设第一个人抓n粒(当然这个家伙不是白痴(n< 20)),第二个人抓的数目不可能让第三个人有选择中间值的可能(如果选择第三个人能选择中间值的话,第四个人和第五个人同样可以选择中间值,必死无疑),那么第二个人可能抓n-1,n+1粒。第三个人会做一个选择(他同样会取前面两个人的中间值)得到k=(2n-1)/2或者(2n+1)/2,但是对他来说,他得作出一个选择,是取k,还是k+1,不管怎么样,总得跟前面两个人中的一个人相同;同理,第四个人和第五个人也必须取中间值,结果他们没有一个人能活下来.
我觉得他们活下来得概率是一样的.
Top
回复人:ilelf(獨毒) ( 一级(初级)) 信誉:100 2005-08-19 12:49:00 得分:0
?
我个人感觉好象全部都没有活命的机会似的。
由于每个人都要选不大不小的数,所以他肯定要先算一下前面的人选的数的平均数。
假如ai为每个人选的颗数.
第三个人选的时候肯定先算是一下(a1+a2)/2,假如这个时候选出来的是整数的话,如第一个人和第二个人选的数之差大于等于2,那么第三个人肯定挑a3=(a1+a2)/2颗,[例如a1=6,a2=8,a3=7]后面的人全都挑一样的7,于是只有1,2死。
但由于大家都是联明人,2肯定不会这样做,因为那样他必死。
所以我觉得可能的情况是1选了数a1,二则选|a2-a1|=1的数,第三个人算(a1+a2)/2的时候得到一个中间数,于是他只能从a1,a2里随机挑一个,后面的类似,于是最后所有人挑的数不是a1,就是a2,所以全部都死。
Top
回复人:yjy1001(蓝鲸--优秀得郁闷的鱼) ( 一级(初级)) 信誉:100 2005-08-19 13:12:00 得分:0
?
如果都是聪明人 差不多如楼上分析
最后全部都要死
中间的相同,2头的因为是最大或最小,
最终全部都挂……
Top
回复人:OMA_yudy(太平洋深深) ( 一级(初级)) 信誉:100 2005-08-19 15:11:00 得分:0
?
聪明反被聪明误啊。可怜的五个白痴。
Top
回复人:guangtougl(guangtougl) ( 一级(初级)) 信誉:100 2005-08-19 15:39:00 得分:0
?
看楼上分析,好像全都的死
Top
回复人:luojxun() ( 一级(初级)) 信誉:100 2005-08-19 16:01:00 得分:0
?
我想应该是第四个人,他可以保证自己的豆不会少与第五人,而且他可以知道前几位手里的斗的平均数.好的情况:如果前几位的平均数大于20,他只要保证自己的豆大于剩余的1/2多一颗,他肯定不会死.若小于 20,将前三位拿的豆总数除以3余数为0,拿平均数,最坏是他们拿一样的数目豆,则5人都要死.否则他可活.余1,2则说明起码有一个人手里的豆大于平均数,也拿平均数.那他手里的豆将小于他们四位的平均数第五位绝对不会那大于平均数的豆,那要看他的运气了,下面的情况大家考虑吧.
Top
回复人:luojxun() ( 一级(初级)) 信誉:100 2005-08-19 16:05:00 得分:0
?
第5位要保证自己不死的机会最大,他应该拿前四位手里豆数的平均数.
Top
回复人:luojxun() ( 一级(初级)) 信誉:100 2005-08-19 16:48:00 得分:0
?
其实我的结果5人都没生存的机会.首先题目还得说明不能全拿,因为第一个的生存机会最小,若第一位全拿那5个都死,第一位没得选择,但他必考虑到最有利第四人的情况,他肯定不会拿大于20的豆,第二位知道第一为拿的豆数为了自己生存希望大些会拿比第一个人少一颗的豆,第三个出于以上考虑肯定拿与第二个人一样数的豆,第四照以上考虑拿的与第2,3人一样的数,第四个人也肯定那与第2,3,4人一样数的豆.那5人都死.
Top
回复人:canoe_eyes(阿里) ( 一级(初级)) 信誉:100 2005-08-19 17:00:00 得分:0
?
第一个
Top
回复人:whzhhit(茫茫雪飘) ( 一级(初级)) 信誉:100 2005-08-19 19:12:00 得分:0
?
我也觉得1,2,3,4,5都必死无疑,分析如下:
因为他们每个人都不会取大于20 的数,第一个当然也不会取19,也不会取1,2 ,否则他将是最小者。现1号在3到18之间随即取一个数,比如 12 吧,而2号只能选13或者11。因为他知道选相同者必死,所以不会选12,而且他也不愿意给别人取1,2号中间数的机会,因而也不会选其它的数,而选13 和11的概率相同,现假定他选11吧,而3号会选10,11,12,13 。因为他知道:5号没有选择的机会而必死,根据“他们的原则是先求保命,再去多杀人”这一原则,5号一定会选择一个垫背的,而4号跟5号一样也没有选择的机会,他自己不能活命,当然也不会给别人活命的机会,所以它同样会选择一个垫背的。如果3号选择11或者12 ,他必死,而4号和5号会选择11或者12而且一定有一个会选择3号未选的那个数。如果3号选择10或者13,那4号和5号一定有一个人会选择前三个人的中间数12,而另一个人会在三个数中任选一个。
Top
回复人:whzhhit(茫茫雪飘) ( 一级(初级)) 信誉:100 2005-08-19 19:13:00 得分:0
?
1号如果取19或者20,他将会是最大者
Top
回复人:smile2005() ( 一级(初级)) 信誉:98 2005-08-19 23:06:00 得分:0
?
是概率问题吗?嘿嘿......
Top
回复人:yifeng4592(栋冬) ( 一级(初级)) 信誉:100 2005-08-19 23:38:00 得分:0
?
这是一道for 的两层循环题吧
Top
回复人:lanyus() ( 一级(初级)) 信誉:100 2005-08-19 23:59:00 得分:0
?
这五个人谁也没办法确定他拿的数量不是最大或者最小,因为这100个绿豆没有一个绝对的分法让自己知道是否不属于最大或者最小。
这五个聪明人最后拿的数量至少有四个应该是连续的数字,那么,当第一个人拿了之后,他的数字成为最大或者最小的概率是1/2*1/2*1/2*1/2,第二个人成为最大或者最小的概率是1/2*1/2*1/2,第三个人的概率是1/2*1/2。。。。。
所以最后成为最大或者最小的概率是第一个人最小,也就是说他的生存概率最大。
Top
回复人:defyer007(挑战者---在学MFC呢) ( 三级(初级)) 信誉:100 2005-08-20 00:29:00 得分:0
?
看了楼上的各位解答,好象基本上都是考虑的一些特殊情况下的解,但是从概率与统计理论的角度来说,应该考虑所有的情况,然后统计结果,再看谁的生存概率最大,偶有两个想法:
1.用条件概率算,每颗豆子被取或不被取,概率分别为1/2,将每个人的取豆行为看成一个100重伯努力实验,再用条件概率的公式计算。
2.虽然有点笨,但偶觉得可以写个循环,先设n1,n2,n3,n4,n5,n1从1到96循环,n2从1到100-n1循环,n3从1到100-n1-n2 循环,依次类推(上面是5个外层循环)然后在内层中判断去掉最大和最小的数(可以重复)将剩下的n(i)所对应的一个统计数组(假设为 SurvivRate[i],i=1,2,3,4,5)+1,表示增加它的存活概率;最后,SurvivRate数组中最大的那个数对应的下标号就是解了。
愚见:)
Top
回复人:luojxun() ( 一级(初级)) 信誉:100 2005-08-20 08:30:00 得分:0
?
这种问题是无法用程序模拟的,据我所知还没谁可以写出模拟人的思维软件,也没那台电脑有这么高的智能.不用考虑太多的可能性.因为从第三人开始他拿前面人手里的豆数的平均数(取整数部分),则他手里的豆数大于一个人,小与另一人可能性最高.他必会如此选择.
Top
回复人:sxinyying(水心云影!) ( 一级(初级)) 信誉:100 2005-08-21 02:50:00 得分:0
?
我准备这几天都来这里了,虽然我不会
Top
回复人:magic_laubj2008(C++初学者) ( 一级(初级)) 信誉:100 2005-08-21 17:55:00 得分:0
?
好耐啦
Top
回复人:whzhhit(茫茫雪飘) ( 一级(初级)) 信誉:100 2005-08-25 14:59:00 得分:0
?
怎么没有人做了呢??
Top
回复人:caio0(戴 强) ( 一级(初级)) 信誉:100 2005-08-26 14:45:00 得分:0
?
我觉得他们没一个能活
首先,第一个人抓的时候,或考虑到后面的人是怎么想的
也会考虑到后面的人想他是怎么想的,一直往下想下去,。。。。。
因为他们是一样的聪明,也都知道别人和他一样聪明
这样就会导致所有人抓的都一样。(如果有一个让自己存活下来的值)


这样他们存活的概率相同0。
这叫同生死,共命运。
Top
回复人:caio0(戴 强) ( 一级(初级)) 信誉:100 2005-08-26 15:00:00 得分:0
?
如果4个人分80颗怎么样呢?
如果三个人分60颗呢?(这个不用说了)
Top
回复人:zyang() ( 一级(初级)) 信誉:100 2005-08-27 19:21:00 得分:0
?
说点搞笑的:至少抓一颗,可没说最多抓几颗。 100颗绿豆能有多少,第一个人全抓了得了,其他人 全枪毙。嘿嘿
Top
回复人:zyang() ( 一级(初级)) 信誉:100 2005-08-27 19:22:00 得分:0
?
哦,没注意,抓得最多也要死
Top
回复人:xiaocai0001(萧筱雨) ( 四级(中级)) 信誉:100 2005-08-27 21:09:00 得分:0
?
看看吧
早有人讨论过了
http://community.csdn.net/Expert/topic/4167/4167667.xml?temp=.0713312
Top
回复人:xiaocai0001(萧筱雨) ( 四级(中级)) 信誉:100 2005-08-27 21:11:00 得分:0
?
再贴一个类似的问题
[以下转帖]


海盗分金问题异调


这是一帮亡命之徒,在海上抢人钱财,夺人性命,干的是刀头上舔血的营生。在我们的印象中,他们一般都瞎一只眼,用条黑布或者讲究点的用个黑皮眼罩把坏眼遮上。他们还有在地下埋宝的好习惯,而且总要画上一张藏宝图,以方便后人掘取。不过大家是否知道,他们是世界上最民主的团体。参加海盗的都是桀骜不驯的汉子,是不愿听人命令的,船上平时一切事都由投票解决。船长的唯一特权,是有自己的一套餐具——可是在他不用时,其他海盗是可以借来用的。船上的唯一惩罚,就是被丢到海里去喂鱼。
  现在船上有若干个海盗,要分抢来的若干枚金币。自然,这样的问题他们是由投票来解决的。投票的规则如下:先由最凶猛的海盗来提出分配方案,然后大家一人一票表决,如果有50%或以上的海盗同意这个方案,那么就以此方案分配,如果少于50%的海盗同意,那么这个提出方案的海盗就将被丢到海里去喂鱼,然后由剩下的海盗中最凶猛的那个海盗提出方案,依此类推。
  我们先要对海盗们作一些假设。
  1) 每个海盗的凶猛性都不同,而且所有海盗都知道别人的凶猛性,也就是说,每个海盗都知道自己和别人在这个提出方案的序列中的位置。另外,每个海盗的数学和逻辑都很好,而且很理智。最后,海盗间私底下的交易是不存在的,因为海盗除了自己谁都不相信。
  2) 一枚金币是不能被分割的,不可以你半枚我半枚。
  3) 每个海盗当然不愿意自己被丢到海里去喂鱼,这是最重要的。
  4) 每个海盗当然希望自己能得到尽可能多的金币。
  5) 每个海盗都是现实主义者,如果在一个方案中他得到了1枚金币,而下一个方案中,他有两种可能,一种得到许多金币,一种得不到金币,他会同意目前这个方案,而不会有侥幸心理。总而言之,他们相信二鸟在林,不如一鸟在手。
  6) 最后,每个海盗都很喜欢其他海盗被丢到海里去喂鱼。在不损害自己利益的前提下,他会尽可能投票让自己的同伴喂鱼。
  现在,如果有10个海盗要分100枚金币,将会怎样?
  要解决这类问题,我们总是从最后的情形向后推,这样我们就知道在最后这一步中什么是好的和坏的决定。然后运用这个知识,我们就可以得到最后第二步应该作怎样的决定,等等等等。要是直接就从开始入手解决问题,我们就很容易被这样的问题挡住去路:“要是我作这样的决定,下面一个海盗会怎么做?”  以这个思路,先考虑只有2个海盗的情况(所有其他的海盗都已经被丢到海里去喂鱼了)。记他们为P1和P2,其中P2比较凶猛。P2的最佳方案当然是:他自己得 100枚金币,P1得0枚。投票时他自己的一票就足够50%了。  往前推一步。现在加一个更凶猛的海盗P3。P1知道——P3知道他知道——如果P3的方案被否决了,游戏就会只由P1和P2来继续,而P1就一枚金币也得不到。所以P3知道,只要给P1一点点甜头,P1就会同意他的方案(当然,如果不给 P1一点甜头,反正什么也得不到,P1宁可投票让P3去喂鱼)。所以P3的最佳方案是:P1得1枚,P2什么也得不到,P3得99枚。
  P4的情况差不多。他只要得两票就可以了,给P2一枚金币就可以让他投票赞同这个方案,因为在接下来P3的方案中P2什么也得不到。P5也是相同的推理方法只不过他要说服他的两个同伴,于是他给每一个在P4方案中什么也得不到的P1和P3一枚金币,自己留下98枚。
  依此类推,P10的最佳方案是:他自己得96枚,给每一个在P9方案中什么也得不到的P2,P4,P6和P8一枚金币。
  下面是以上推理的一个表(Y表示同意,N表示反对):
  P1  P2   0  100   N  Y   P1  P2 P3   1  0  99   Y  N  Y   P1  P2  P3  P4   0  1   0  99   N  Y   N  Y   P1 P2  P3  P4  P5   1  0  1  0  98   Y  N  Y  N  Y   ……   P1  P2  P3  P4  P5  P6  P7  P8  P9  P10   0   1  0   1  0  1   0  1   0  96   N   Y  N  Y  N  Y   N  Y  N   Y
  现在我们将海盗分金问题推广:
  1) 改变一下规则,投票中方案必须得到超过50%的票数(只得到50%票数的方案的提出者也会被丢到海里去喂鱼),那么如何解决10个海盗分100枚金币的问题?
  2) 不改变规则,如果让500个海盗分100枚金币,会发生什么?
  3) 如果每个海盗都有1枚金币的储蓄,他可以把这枚金币用在分配方案中,如果他被丢到海里去喂鱼,那么他的储蓄将被并在要分配的金币堆中,这时候又怎样?
  通过对规则的细小改变,海盗分金问题可以有许多变化,但是最有趣的大概是1)和2)(规则仍为50%票数即可)的情况,本帖只对这两种情况进行讨论。
  首先考虑1)。现在只有P1和P2的情形变得对P2其糟无比:1票是不够的,可是就算他把100枚金币都给P1,P1也照样会把他丢到海里去。可是P2 很关键,因为如果P3进行分配方案的话,即使他一枚金币也不给P2,P2也会同意,这样一来P3就有P2这张铁票!P3的最佳方案就是:独吞100枚金币。
  P4要3张票,而P3是一定反对他的,而如果不给P2一点甜头,P2也会反对,因为P2可以在P3的方案中得救,目前为什么不把P4丢到海里呢?所以要分别给P1和P2一枚金币,这样P4就有包括他自己1票的3票。P4的方案为:P1,P2每人1枚金币,他自己98枚。
  P5的情况要复杂点,他也要3票。P4是会反对他的,所以不用给,给P3一枚金币就能使他支持自己的方案,因为在接下来的P4方案中他什么也得不到。问题是P1 和P2:只要其中有一个支持就可以了。可是只给1枚金币是不行的,P4方案中他们一定有1枚金币可得,所以只要在他们中随便选一个,给2枚金币,另一个就对不起了,不给。这样P5的方案是:自己97枚,P3得1枚,P1或P2得2枚。
  P6的方案建立在P5的上面,只要给每个P5方案中不得益的海盗1枚金币。要注意的是,P1和P2都应该看作在P5方案中不得益的:他们可能得2枚,可是也可能1枚不得,所以只要P6给他们1枚金币,根据“二鸟在林,不如一鸟在手“的原则,就可以让他们支持P6的方案。所以P6的方案是唯一的:P1,P2,P4每人1枚金币,P6自己拿97枚。
  这样继续下去,P9的方案是:P3,P5,P7每人1枚金币,然后在P1,P2,P4,P6中任选一人给2枚金币,P9自己得95枚。最后,P10的方案是唯一的:P1,P2,P4,P6,P8每人1枚金币,P10自己得95枚。  2)是最有趣的(提醒:我们回到50%票即可的规则)。原题解中的推理过程直到 200个海盗都是成立的:P200给每个偶数号的海盗1枚金币,包括他自己,其他海盗什么也得不到。从P201开始,继续推理就变得有点困难了:P201 为了不被丢到海里去,必须什么也不留给自己,而给从P1到P199中所有奇数号海盗每人1枚金币,从而争取到100票,加上他自己1票,逃过一劫。 P202也什么都得不到,他必须用这100枚金币买通100个从P201的方案中什么也得不到的海盗,要注意到现在这个方案不是唯一的:P201的方案中得不到金币的海盗是所有奇数号的海盗,有101个(包括P201),所以有101种方案。
  P203必须得到102票,除了自己的1票外,他只有100枚金币,所以只能买到100票,所以可怜的家伙就被丢到海里喂鱼了。但是,P203是个很重要的角色,因为P204知道如果自己的方案不被通过, P203也一样会完蛋,所以他有P203的一张铁票。所以P204可以大出一口气:他自己一票,加上P203一票,然后加上用100枚金币买的确100 票,他就得救了!100个有幸得到1枚金币的海盗,可以是P1到P202中任何100个:因为其中的偶数号的从P202的方案中什么也得不到,如果 P204给他们中某个海盗1枚金币,这个海盗一定会赞同这个方案;而编号为奇数的海盗呢,只是有可能从P202的方案中得益罢了(可能性为 100/101),所以根据“二鸟在林,不如一鸟在手“的原则,如果能得到1枚金币,他也会赞同这个方案。
  接下去P205是不能把希望放在 P203和P204这两张票上的,因为就算他被丢到海里去,P203和P204还可以通过P204的方案机会活下来。P206虽然可以靠P205的铁票,加上自己1票和100枚金币搞到的100票,只有102票,所以他也被丢到海里喂鱼。P207好不了多少,他需要104票,而他自己以及P205和 P206的铁票加上100枚金币搞到的100票只有103票——只好下海。
  P208运气比较好,他同样也要104票,可是P205,P206,P207都会投票赞成他的方案!加上他自己的1票和买来的100票,他终于逃脱了做鱼食的命运。
  这样我们就有了一种可以一直推下去的新逻辑。海盗可以什么也不留给自己,买上100票,然后依靠一部分一定会被丢下海的海盗的铁票,从而让自己的方案通过。有这样运气的海盗分别是P201,P202,P204,P208,P216,P232,P264,P328和P456……我们看到这样的号码是200 加上一个2的次幂。  哪些海盗是受益者呢,显然铁票是不用(不能)给金币的。所以只有上一个幸运号码及他以前的那些海盗才有可能得到1枚金币。于是我们得到500海盗分100枚金币的结论是:前44个最凶猛的海盗被丢进海里,然后P456给P1到P328中的100个海盗每人1枚金币。
  就这样,最凶猛的海盗被丢进海里,而比较凶猛的什么也得不到,而只有最温柔的那些海盗,才有可能得到1枚金币。正如《马太福音》所说:“温柔的人有福了,因为他们必承受地土!”




12.
主  题: 一个面试题,怎么都想不出来,请高手指点!!!!
作  者: zr3100 ()
等  级:
信 誉 值: 100
所属论坛: C/C++ C++ 语言
问题点数: 20
回复次数: 31
发表时间: 2005-8-12 10:03:50




要求不用到第三个变量,交换两个整数的值!!!
回复人:oo(为了名副其实,努力学习oo技术ing) ( 两星(中级)) 信誉:110 2005-8-12 10:06:58 得分:0
?


so old
Top
回复人:xteaj(半桶水) ( 一星(中级)) 信誉:97 2005-8-12 10:07:04 得分:0
?


int a, b;
....
a += b;
b = a - b;
a -= b;//完成交换
....


Top
回复人:zr3100() ( 一级(初级)) 信誉:100 2005-8-12 10:11:53 得分:0
?


多谢指点


Top
回复人:qiek(道可道非常道) ( 一级(初级)) 信誉:100 2005-8-12 10:12:25 得分:0
?


用异或运算符 ^
int a = 5, b=3;
a = a^b;
b = a^b;
a = a^b;
cout<<a<<" "<<b;
Top
回复人:T_Kun(小唐) ( 一级(初级)) 信誉:100 2005-8-12 17:00:39 得分:0
?


楼上的方法同或运算符一样可以
Top
回复人:alrcool(胡志屏) ( 一级(初级)) 信誉:98 2005-8-12 17:08:30 得分:0
?


void Swap(int *a,int *b)
{
*a = *a + *b;
*b = *a - *b;
*b = *a - *b;
}
Top
回复人:winzz123(忙啊盲) ( 一级(初级)) 信誉:100 2005-8-12 18:45:05 得分:0
?


复人: qiek(道可道非常道) ( ) 信誉:100 2005-08-12 10:12:00 得分: 0




用异或运算符 ^
int a = 5, b=3;
a = a^b;
b = a^b;
a = a^b;
cout<<a<<" "<<b;
这个更科学!因为不会出现溢出!




Top
回复人:whatsouta(某疯子) ( 二级(初级)) 信誉:100 2005-8-12 19:05:35 得分:0
?


复人: qiek(道可道非常道) ( ) 信誉:100 2005-08-12 10:12:00 得分: 0




用异或运算符 ^
int a = 5, b=3;
a = a^b;
b = a^b;
a = a^b;
cout<<a<<" "<<b;
这个更科学!因为不会出现溢出!


还要快一些


Top
回复人:U2002484(20024804) ( 一级(初级)) 信誉:100 2005-8-13 11:28:17 得分:0
?


初学者吧,这个问题都第一次遇到还去面试,你还是多学点吧
Top
回复人:LoveYouJustOneDay(哈哈) ( 三级(初级)) 信誉:100 2005-8-13 12:10:08 得分:0
?


无聊的面试题
每一个有准备的
或者常看计算机杂志的人
都见过这个
Top
回复人:zousoft(菜菜鸟的战斗诗歌) ( 一级(初级)) 信誉:100 2005-8-13 12:33:58 得分:0
?


这种题纯属瞎鬼,除非是搞编译器。否则开发项目里,谁要是写这样的代码,第一该被踢的就是他。
Top
回复人:cuizm(射天狼) ( 三星(高级)) 信誉:100 2005-8-13 14:04:29 得分:0
?


是啊,好无聊的公司啊~~~~~
Top
回复人:henan_lujun(地平风线) ( 二级(初级)) 信誉:100 2005-8-13 14:15:22 得分:0
?


其实,拿这种题来作为面试的人,公司该先把他K掉,一点都不负责任的!




Top
回复人:Sandy_Y() ( 一级(初级)) 信誉:100 2005-8-13 15:03:49 得分:0
?


a=a+b;
b=a-b;
a=a-b;
不就交换了吗
Top
回复人:WindYou(WindYou) ( 二级(初级)) 信誉:100 2005-8-13 15:16:40 得分:0
?


用寄存器可以吗?
int a = 0;
int b = 1;


asm mov edx, a
a = b;
asm mov b, edx
Top
回复人:beginnow() ( 一级(初级)) 信誉:100 2005-8-13 15:30:14 得分:0
?


再简单的问题也能反映出水平,楼主的题写一个模板类更好,可以交换任何类型。
Top
回复人:N_thread() ( 一级(初级)) 信誉:100 2005-8-13 15:59:00 得分:0
?


初中学VB的时候,讲赋值的时候说过了。
Top
回复人:gucheng2008(孤城) ( 一级(初级)) 信誉:100 2005-8-13 19:14:06 得分:0
?


呵呵,我也第一次见这样的题目啊!长见识啊!!
Top
回复人:xcz05059(鲜橙汁) ( 一级(初级)) 信誉:100 2005-8-13 22:10:47 得分:0
?


出这题目的公司,没水平。。。个人观点
Top
回复人:wq1982718() ( 一级(初级)) 信誉:100 2005-8-14 22:34:28 得分:0
?


“这种题纯属瞎鬼,除非是搞编译器。否则开发项目里,谁要是写这样的代码,第一该被踢的就是他。

同意这个观点!!
Top
回复人:bugebear3() ( 二级(初级)) 信誉:100 2005-8-19 16:36:02 得分:0
?


其实题目挺有意思的,怎么老大们都反应得这么激烈?
Top
回复人:zengkun100(夜的孩子) ( 一级(初级)) 信誉:99 2005-8-19 21:21:21 得分:0
?


这个题目不说是计算机的题吧,光说是数学题就蛮有意思的。
所以xteaj(半桶水) 的方法是很好的数学解决方案
而qiek(道可道非常道)的方法是很好的计算机解决方案
Top
回复人:cmoring(my study will go on) ( 二级(初级)) 信誉:100 2005-8-25 9:56:06 得分:0
?


据说华为就有一年有这个笔试题目
Top
回复人:ruiding(瑞丁) ( 一级(初级)) 信誉:100 2005-8-25 10:09:35 得分:0
?


朗讯也有这个面试题...
Top
回复人:wonderfullzh(天堂电影院) ( 一级(初级)) 信誉:100 2005-8-26 13:50:32 得分:0
?


今天又学了一招,小弟佩服,佩服!!!
Top
回复人:ftkghost(小鹏) ( 四级(中级)) 信誉:100 2005-8-26 15:05:09 得分:0
?


void swap(int &a, int &b)
{
a=a+b;
b=a-b;
a=a-b;
}
Top
回复人:zwl327(疾劲野风) ( 二级(初级)) 信誉:100 2005-8-26 15:18:40 得分:0
?


这个题到校园招聘还是很好的,而且能用a^b这种方法的,非常少!
Top
回复人:maolixian() ( 一级(初级)) 信誉:100 2005-8-26 15:36:24 得分:0
?


我也是第一次遇到呀
Top
回复人:OMA_yudy(太平洋深深) ( 一级(初级)) 信誉:100 2005-8-26 15:52:37 得分:0
?


a^b的方法并不快,也不好读。




00401028 mov dword ptr [ebp-4],1


0040102F mov dword ptr [ebp-8],2A6h


10: a=a+b;


00401036 mov eax,dword ptr [ebp-4]


00401039 add eax,dword ptr [ebp-8]


0040103C mov dword ptr [ebp-4],eax


11: b=a-b;


0040103F mov ecx,dword ptr [ebp-4]


00401042 sub ecx,dword ptr [ebp-8]


00401045 mov dword ptr [ebp-8],ecx


12: a=a-b;


00401048 mov edx,dword ptr [ebp-4]


0040104B sub edx,dword ptr [ebp-8]


0040104E mov dword ptr [ebp-4],edx






///


00401028 mov dword ptr [ebp-4],1


0040102F mov dword ptr [ebp-8],2A6h


10: a=a^b;


00401036 mov eax,dword ptr [ebp-4]


00401039 xor eax,dword ptr [ebp-8]


0040103C mov dword ptr [ebp-4],eax


11: b=a^b;


0040103F mov ecx,dword ptr [ebp-4]


00401042 xor ecx,dword ptr [ebp-8]


00401045 mov dword ptr [ebp-8],ecx


12: a=a^b;


00401048 mov edx,dword ptr [ebp-4]


0040104B xor edx,dword ptr [ebp-8]


0040104E mov dword ptr [ebp-4],edx




Top
回复人:SammyLan(没有窍门,只有努力.LOVE 33 4 Ever ) ( 二级(初级)) 信誉:98 2005-8-26 17:18:47 得分:0
?


MARK


Top
回复人:sinlff() ( 一级(初级)) 信誉:100 2005-8-26 18:25:14 得分:0
?


怎么发帖子啊


13.
主  题: 二道面试题,关于链表的,急!
作  者: ray9901 (ray)
等  级:
信 誉 值: 100
所属论坛: C/C++ 新手乐园
问题点数: 20
回复次数: 38
发表时间: 2005-8-22 20:58:09




1。假设有一个4节点的单链表,请设计一个C语言递归函数,实现链表的逆序。


2。编写一个C函数,实现将无符号字符类型数的高位和低位的逆转。


回复人:SammyLan(没有窍门,只有努力.LOVE 33 4 Ever ) ( 二级(初级)) 信誉:98 2005-8-22 21:26:59 得分:4
?


MARK
冲凉先
Top
回复人:SammyLan(没有窍门,只有努力.LOVE 33 4 Ever ) ( 二级(初级)) 信誉:98 2005-8-22 21:47:34 得分:0
?


Node* Func(Node* p)
{
if(p->next->next=NULL)
{
p->next->next=p;
p->next->next->next=NULL:
p=p->next;
return p;
}
else
{
Node *temp=p;
p=Func(p);
temp->next->next=temp;
temp->next=NULL
return p;
}
}
Top
回复人:SammyLan(没有窍门,只有努力.LOVE 33 4 Ever ) ( 二级(初级)) 信誉:98 2005-8-22 21:48:51 得分:0
?


没有测试过,上面的估计可以通过
学习语言而不好好学习数据结构和算法
悲哀...............
Top
回复人:mybliao(永远在线) ( 一级(初级)) 信誉:100 2005-8-22 22:22:48 得分:0
?


p->next->next=NULL


有问题吧
Top
回复人:SammyLan(没有窍门,只有努力.LOVE 33 4 Ever ) ( 二级(初级)) 信誉:98 2005-8-22 22:25:36 得分:0
?


void Func(unsigned int & ui)
{
unsigned int temp=0;
for(int i=0;i<32;++i)
{
temp=temp<<1;
temp|=ui&1;
ui=ui>>1;
}
ui=temp;
}
方法很苯
Top
回复人:SammyLan(没有窍门,只有努力.LOVE 33 4 Ever ) ( 二级(初级)) 信誉:98 2005-8-22 22:28:05 得分:0
?


第一个的解答估计没有问题
Top
回复人:Bobby136(鄙视地球人!) ( 一级(初级)) 信誉:100 2005-8-23 0:14:01 得分:0
?


第2题
void F(unsigned char &c)
{
if((c&1<<7)^(c&1<<0)<<7)c^=(1<<7|1<<0);
if((c&1<<6)^(c&1<<1)<<5)c^=(1<<6|1<<1);
if((c&1<<5)^(c&1<<2)<<3)c^=(1<<5|1<<2);
if((c&1<<4)^(c&1<<3)<<1)c^=(1<<4|1<<3);
}
Top
回复人:Bobby136(鄙视地球人!) ( 一级(初级)) 信誉:100 2005-8-23 0:24:17 得分:2
?




效率更低的
void f2(unsigned char &c)
{
unsigned char tmp=0;
for(int i=0;i<8;i++)
if(c&1<<i)tmp|=1<<(7-i);
c=tmp;
}
Top
回复人:baiywcwttfln(A-De) ( 一级(初级)) 信誉:100 2005-8-23 3:29:00 得分:1
?


LNode * func(LNode * l,LNode * p)//初始时p=l;l为头指针
{
if(!p->next)return l;
LNode *q;
q=p->next;
p->next=q->next;
q->next=l;
return func(q,p);


}


Top
回复人:Bobby136(鄙视地球人!) ( 一级(初级)) 信誉:100 2005-8-23 10:10:00 得分:0
?


class List{
Node*first;
public:


void Reserve(Node*p,Node*parent)
{
assert(p);
Node *tmp=p->next;
p->next=parent;
if(tmp)
{
Reserve(tmp,p);
}
else
{
first=p;
}
}


void Reserve()
{
Reserve(first,NULL);
}
}
Top
回复人:zhouhuahai(道号"虚无") ( 三级(初级)) 信誉:100 2005-8-23 10:40:20 得分:0
?


楼上没看清楚题,人家要的是C函数,否则就直接用bitset来做不是更容易?
Top
回复人:Mars_xlb(小宝) ( 一级(初级)) 信誉:100 2005-8-23 11:20:14 得分:0
?


怎么没有人做第二题啊
Top
回复人:Mars_xlb(小宝) ( 一级(初级)) 信誉:100 2005-8-23 11:23:44 得分:0
?


怎么觉得第二题的题目描述的不太清楚啊,哪位老大解释一下
Top
回复人:luocong(静下心来读点书!) ( 一级(初级)) 信誉:100 2005-8-23 11:44:23 得分:2
?


unsigned char convert(unsigned char c)
{
return ((c & 0x0F) << 4) + ((c & 0xF0) >> 4);
}


int main()
{
unsigned char c1 = 78;
unsigned char c2 = convert(c1);
}
Top
回复人:Bobby136(鄙视地球人!) ( 一级(初级)) 信誉:100 2005-8-23 12:00:08 得分:0
?


回复人: zhouhuahai(道号"虚无") ( ) 信誉:100 2005-08-23 10:40:00 得分: 0


楼上没看清楚题,人家要的是C函数,否则就直接用bitset来做不是更容易?


----------------------------------------------------------------------------------
你指的是第一题还是第二题


Top
回复人:improgrammer(无忌) ( 四级(中级)) 信誉:100 2005-8-23 13:02:53 得分:2
?


//第一题要求用递归算法,可以这样:


Node* Reverse(Node *head, Node* prev)
{
Node *p = head->next;
head->next = prev;
if (p)
return Reverse(p, head);
else
return head;
}


int main()
{
extern Node *head;
head = Reverse(head, NULL);
//....
}


//第二题如果指(10011100)->(00111001),则如此:
unsigned char reverse(unsigned char v)
{
unsigned char v1, v2;
v1 = v & 128;
v2 = v & 1;
if (v1)
{
v |= 1;
}
if (v2)
{
v |= 128;
}
//
v1 = v & 64;
v2 = v & 2;
if (v1)
{
v |= 2;
}
if (v2)
{
v |= 64;
}
//
v1 = v & 32;
v2 = v & 4;
if (v1)
{
v |= 4;
}
if (v2)
{
v |= 32;
}
//
v1 = v & 16;
v2 = v & 8;
if (v1)
{
v |= 8;
}
if (v2)
{
v |= 16;
}
//
return v;
}
Top
回复人:improgrammer(无忌) ( 四级(中级)) 信誉:100 2005-8-23 13:05:07 得分:0
?


//第二题更正:
unsigned char reverse(unsigned char v)
{
unsigned char v1, v2, ret = 0;
v1 = v & 128;
v2 = v & 1;
if (v1)
{
ret |= 1;
}
if (v2)
{
ret |= 128;
}
//
v1 = v & 64;
v2 = v & 2;
if (v1)
{
ret |= 2;
}
if (v2)
{
ret |= 64;
}
//
v1 = v & 32;
v2 = v & 4;
if (v1)
{
ret |= 4;
}
if (v2)
{
ret |= 32;
}
//
v1 = v & 16;
v2 = v & 8;
if (v1)
{
ret |= 8;
}
if (v2)
{
ret |= 16;
}
//
return ret;
}


Top
回复人:improgrammer(无忌) ( 四级(中级)) 信誉:100 2005-8-23 13:18:22 得分:1
?


//如果喜欢短一点的代码:
unsigned char reverse(unsigned char v)
{
unsigned char masks[8] = {1,2,4,8,16,32,64,128};
unsigned char ret = 0;
char i = 0;
for (i = 0; i<4; ++i)
{
unsigned char v1 = v & masks[i];
unsigned char v2 = v & masks[7-i];
if (v1)
{
ret |= masks[7-i];
}
if (v2)
{
ret |= masks[i];
}
}
return ret;
}
Top
回复人:Mars_xlb(小宝) ( 一级(初级)) 信誉:100 2005-8-23 13:34:09 得分:0
?


描述一下思路啊
Top
回复人:antijpn(antijpn) ( 一星(中级)) 信誉:100 2005-8-23 13:47:30 得分:0
?


直接求代码,转新手乐园
Top
回复人:wxdvc(csdn) ( 一级(初级)) 信誉:99 2005-8-23 14:07:13 得分:0
?


luocong(静下心来读点书!) 应该是最简单了吧.
Top
回复人:learn100(learn100) ( 一级(初级)) 信誉:100 2005-8-23 23:53:12 得分:0
?


第一题使用一个全局堆栈就可以了。每次返回的是栈顶元素。


Top
回复人:SammyLan(没有窍门,只有努力.LOVE 33 4 Ever ) ( 二级(初级)) 信誉:98 2005-8-24 1:19:19 得分:0
?


void Func(unsigned int & ui)
{
unsigned int temp=0;
int size=8*sizeof(ui);
for(int i=0;i<size;++i)
{
temp=temp<<1;
temp|=ui&1;
ui=ui>>1;
}
ui=temp;
}
简练明了,可移植性高




Top
回复人:bigseabigsky(海阔天空) ( 一级(初级)) 信誉:100 2005-8-24 9:16:24 得分:1
?


还有点小问题
1、类型应该用unsigned char
2、要求是c函数,不应该用引用的
Top
回复人:bigseabigsky(海阔天空) ( 一级(初级)) 信誉:100 2005-8-24 10:06:16 得分:0
?


sorry,没注意你想要表达的可移植性
Top
回复人:SammyLan(没有窍门,只有努力.LOVE 33 4 Ever ) ( 二级(初级)) 信誉:98 2005-8-24 12:39:20 得分:1
?


挂了
C没有引用的
出丑了
Top
回复人:SammyLan(没有窍门,只有努力.LOVE 33 4 Ever ) ( 二级(初级)) 信誉:98 2005-8-24 12:43:08 得分:0
?


而且没有看清楚是无符号字符类型
狂晕
不过思路大概如此
Top
回复人:jinder22(jinder22) ( 一级(初级)) 信誉:100 2005-8-24 12:51:32 得分:3
?


第一题 我在c++里已经条是通过
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <conio.h>
using namespace std;


typedef struct student
{
int data;
struct student *next;
}node;
node *creat()
{
node *head,*p,*s;
int x,cycle=1;
head=(node*)malloc(sizeof(node));
p=head;
while(cycle)
{
printf("\nplease input the data: ");
scanf("%d",&x);
if(x!=0)
{
s=(node *)malloc(sizeof(node));
s->data=x;
printf("\n %d",s->data);
p->next=s;
p=s;
}
else cycle=0;
}
head=head->next;
p->next=NULL;
printf("\n yyy %d",head->data);
return(head);
}


int length(node *head)
{
int n=0;
node *p;
p=head;
while(p!=NULL)
{
p=p->next;
n++;
}
return(n);
}
void print(node *head)


{ node *p;int n;
n=length(head);
printf("\nNow,These %d records are :\n",n);
p=head;
if(head!=NULL)




while(p!=NULL)
{ printf("\n uuu %d ",p->data);
p=p->next;
}






}








node *nizhi(node *head)


{
node *p,*q,*r;
p=head;
q=p->next;
while(q!=NULL)
{
r=q->next;
q->next=p;
p=q;
q=r;
}
head->next=NULL;
head=p;
return(head);
}










int main()
{ node *head,stud;
int n,del_num,insert_num;
head=creat();
print(head);


cout <<"\n nizhi : ";
head=nizhi(head);
print(head);


return 0;
}
Top
回复人:jinder22(jinder22) ( 一级(初级)) 信誉:100 2005-8-24 12:53:49 得分:0
?


node *nizhi(node *head)


{
node *p,*q,*r;
p=head;
q=p->next;
while(q!=NULL)
{
r=q->next;
q->next=p;
p=q;
q=r;
}
head->next=NULL;
head=p;
return(head);
}


Top
回复人:jinder22(jinder22) ( 一级(初级)) 信誉:100 2005-8-24 13:02:28 得分:0
?


第二题 我看不太懂你的意思 我这里有一道题 可以抛砖引玉
用<<,>>,|,&实现一个WORD(2个字节)的高低位交换!!


int main()
{
unsigned short a = 0xABCD;


unsigned short b ;
unsigned short c ,d;


b = (a << 8)&0xff00;
c = (a >> 8)&0x00ff;
d = b | c;
printf("\n%x",b);
printf("\n%x",c);
printf("\n%x",d);


return 0;


}


结果是 CDAB
2俩个字节是16位 前八位为高位 后八位为低位 然后结合
Top
回复人:Bobby136(鄙视地球人!) ( 一级(初级)) 信誉:100 2005-8-24 13:15:48 得分:0
?


C++和C不是一样吗,把引用改成指针,把class改成struct,成员函数提到外面不就行了
Top
回复人:jinder22(jinder22) ( 一级(初级)) 信誉:100 2005-8-24 14:07:30 得分:0
?


ddddddddddddd
Top
回复人:bigseabigsky(海阔天空) ( 一级(初级)) 信誉:100 2005-8-24 15:12:25 得分:1
?


to jinder22(jinder22):方法很对,就是没用递归
Top
回复人:zoulie(珠峰菜鸟) ( 一级(初级)) 信誉:100 2005-8-24 15:30:37 得分:1
?


大哥看清楚点啊,人家说要用低归的。
Top
回复人:ray9901(ray) ( 一级(初级)) 信誉:100 2005-8-24 18:56:04 得分:0
?


基本差不多了,准备结贴,谢谢大家,如果还有更好的方法继续讨论。
Top
回复人:heguosheng(何国胜) ( 一级(初级)) 信誉:100 2005-8-25 15:25:37 得分:1
?


unsigned char c = 0x22;//
c = (c<<7)&0x80|(c<<5)&0x40|(c<<3)&0x20|(c<<1)&0x10|(c>>1)&0x08|(c>>3)&0x04|(c>>5)&0x02|(c>>7)&0x01;
Top
回复人:ray9901(ray) ( 一级(初级)) 信誉:100 2005-08-25 16:01:00 得分:0
?
分数太少,请见凉
Top
回复人:heguosheng(何国胜) ( 一级(初级)) 信誉:100 2005-08-25 16:23:00 得分:0
?
1.
#include <cstdlib>
#include <stdio.h>


struct NODE
{
int iNum;
struct NODE *next;
};


typedef NODE NODE;


NODE* reverse( NODE* p, NODE* q )
{
NODE* temp = p->next; //暂存下一个指针值
p->next = q;
//原表头无后继结点
if( q->iNum == 0 )
q->next = 0;


if( temp == 0 ) //到链尾
return p;
else //未到链尾
return reverse( temp, p );
}


int main()
{
NODE* head;
NODE* p;
NODE* q;
int i;
head = (NODE*)malloc(sizeof( NODE ) );
head->iNum = 0;
q = head;
for( i = 1; i <= 3; i++ )
{
p = (NODE*)malloc(sizeof( NODE ) );
p->iNum = i;
q->next = p;
q = p;
}
q->next = 0;
p->next = 0;
for( p = head; p != 0; p = p->next )
printf( "%d ", p->iNum );


p = reverse( head->next, head );


for( q = p; q != 0; q = q->next )
printf( "%d ", q->iNum );
//free内存...
system("pause");
}
Top


该问题已经结贴 ,得分记录: SammyLan (4)、 Bobby136 (2)、 baiywcwttfln (1)、 luocong (2)、 improgrammer (2)、 improgrammer (1)、 bigseabigsky (1)、 SammyLan (1)、 jinder22 (3)、 bigseabigsky (1)、 zoulie (1)、 heguosheng (1)、




13.
    去DigitalRed笔试时有个这样的题:


三、编写strcpy函数(10分)


   已知strcpy函数的原型是       char *strcpy(char *strDest, const char *strSrc);


   其中strDest是目的字符串,strSrc是源字符串。 (1)不调用C++/C的字符串库函数,请编写函数 strcpy


(2)strcpy能把strSrc的内容复制到strDest,为什么还要char * 类型的返回值?


   我的答案是:


(1)char* strcpy(char* dst, char* src)
     {
        int len = 0;
        while(src[len])
          len++;
        len++;
        dst = new char[len];
        if(dst != NULL){ 
           for(int i=0;i
             dst[i] = src[i];
        }
        return dst;
     }


(2)可以利用返回值判断函数是否成功执行;另指针传递的高效云云。


    回来后还在想这个题,觉得在哪见过。翻了一下电脑上的c++资料,果不其然,在林锐的《高质量c》中有这样的一道题,其答案及评分标准:


(1) 


char *strcpy(char *strDest, const char *strSrc);


{


    assert((strDest!=NULL) && (strSrc !=NULL));   // 2分


    char *address = strDest;                     // 2分


    while( (*strDest++ = * strSrc++) != ‘\0’ )      // 2分


       NULL ;


    return address ;                            // 2分


}


(2)答:为了实现链式表达式。 // 2分


例如       int length = strlen( strcpy( strDest, “hello world”) );


    寒~ 林锐对第二问的解答比我的更说服力一些,而第一问的函数的编写……难道不用为strDest分配空间么?如果用户调用strcpy前没有为strDest 分配足够的空间,岂不有错访问地址的危险?我不服气,便去查看msdn对strcpy的帮助,果然是林锐写的那样啊——


The strcpy function copies strSource, including the terminating null character, to the location specified by strDestination.


Security Note   Because strcpy does not check for sufficient space in strDestination before copying strSource, it is a potential cause of buffer overruns.


微软的源代码:
/***
*char *strcpy(dst, src) - copy one string over another
*
*Purpose:
*       Copies the string src into the spot specified by
*       dest; assumes enough room.
*
*Entry:
*       char * dst - string over which "src" is to be copied
*       const char * src - string to be copied over "dst"
*
*Exit:
*       The address of "dst"
*
*Exceptions:
*******************************************************************************/
char * __cdecl strcpy(char * dst, const char * src)
{
        char * cp = dst;
        while( *cp++ = *src++ )
                ;               /* Copy src over dst */
        return( dst );
}


    汗~ 看来我原先对strcpy的理解有很大偏差了,但搞不懂微软为什么这么写?它这样安全漏洞太多了,必须预先为目标字串分配足够的空间才行,程序员使用这个函数的时候得小心翼翼了,看下面这个例子:


char s[]="123456789";
char d[]="123";
strcpy(d,s);
printf("%s,%s",d,s);


    输出结果是:123456789,56789。没经验的程序员一定会在此大跌眼镜的,源字串竟然被截掉了一部分(截掉的长度恰是目标字串原来的长度。至于原因,应该是连续内存的问题,原来 1234\0123456789\0,strcpy后 123456789\06789\0)!


    而把目标字串的定义在前,源字串定义在后以后,虽然可以看到正确的输出结果:123456789,123456789。但会产生一个运行期错误,原因估计是越过了目标字串的实际空间,访问到了不可预知的地址了。


14.
主  题: 同学面试题目,c语言,有兴趣来看看啊,很有挑战的
作  者: lxinxuan (林子)
等  级:
信 誉 值: 100
所属论坛: C/C++ C语言
问题点数: 50
回复次数: 14
发表时间: 2005-8-16 10:49:59




试题
1:一超市有A,B两个分店,每个分店有个数不等的货柜,每个货柜有种类不等的蔬菜,每种蔬菜有种类不等的蔬菜,每种蔬菜有不同的数量,每个柜台和蔬菜有不同的名称(但是A,B两分店的货柜和蔬菜的名称有可能有重复的).现在A,B两个分店合并,相同的柜台合在一起,相同的蔬菜合在一起得到合并的数量.
用链表来描述分店的不同货柜,按货柜名称的字母升序排列,每个货柜的蔬菜也用链表来描述,按蔬菜名称的字母升序排列,请用c语言编写一个函数,实现两个分店的合并.要求:该函数输入两个分店的链表,返回新店的链表!定义链表的数据结构,并编写程序,要明确空间的申请,释放!
2:用c语言编写一个程序能够将程序自身显示出来(程序越短越好)
即:由源程序编译连接生成可执行的文件,在源程序已经删掉的情况下,运行可执行文件,能将源程序的内容现实出来.
如:源程序aaa.c,编译连接成aaa.exe,然后删掉源程序aaa.c,再运行aaa.exe则在屏幕上显示源程序的全部内容,包括回车,换行等!
不能用文件操作来读取源程序!
这有一个可参考的的程序,但是还不完善,显示内容和源程序还不是一模一样的,可以在这个基础上做完成
例程:main(){char*s="main(){char*s=\"%s\";printf(s,s),}"/,printf(s,s);}
*第一个题目是必须要做的,第二个是选做的,做不出来没关系,就请多帮帮忙了;不好意思,辛苦了哦!
=========================================================================================
以上就是我同学给我的邮件的原文,全部贴上来了...
谁能尽快贴出代码,我给50,我是学c#的,才注册,分不多,另一个号分挺多的,呵呵
回复人:lxinxuan(林子) ( 一级(初级)) 信誉:100 2005-8-16 10:52:33 得分:0
?


对了,可以给我发邮件:linxinxuan@seaskysh.con
Top
回复人:lxinxuan(林子) ( 一级(初级)) 信誉:100 2005-8-16 10:55:38 得分:0
?


这里居然不能编辑的...
错了,我的邮件是linxinxuan@seaskysh.com
Top
回复人:xiaocai0001(萧筱雨) ( 三级(初级)) 信誉:100 2005-8-16 10:55:56 得分:0
?


关注!
Top
回复人:simulationz() ( 一级(初级)) 信誉:100 2005-8-16 10:56:26 得分:0
?


老问题了,CSDN上面早有了,搜一搜就找到了
Top
回复人:Flood1984(峰子) ( 一星(中级)) 信誉:108 2005-8-16 11:34:10 得分:20
?


char *str="int main()\n"
"{\n"
" char *p;\n"
"\n"
" printf(\"char *str=%c\", 34);\n"
" for (p=str; *p; p++) {\n"
" if (*p == 34)\n"
" printf(\"%c%c\", 92, *p);\n"
" else if (*p == 10)\n"
" printf(\"%cn%c%c%c\", 92, 34, 10, 34);\n"
" else\n"
" putchar(*p);\n"
" }\n"
" printf(\"%c%c%c%c%s%c\", 34, 59, 10, 10, str, 10);\n"
"\n"
" return 0;\n"
"}";


int main()
{
char *p;


printf("char *str=%c", 34);
for (p=str; *p; p++) {
if (*p == 34)
printf("%c%c", 92, *p);
else if (*p == 10)
printf("%cn%c%c%c", 92, 34, 10, 34);
else
putchar(*p);
}
printf("%c%c%c%c%s%c", 34, 59, 10, 10, str, 10);


return 0;
}
Top
回复人:VivianSnow(Phoenix) ( 一级(初级)) 信誉:100 2005-8-16 11:48:47 得分:5
?


超容易,早做过了,第二题在acm.tongji.edu.cn里面有
Top
回复人:smstone(石头) ( 一级(初级)) 信誉:100 2005-8-16 11:57:19 得分:2
?


好像没什么技术含量吧
Top
回复人:lbing7(楼主,别再给我非专家分!谢谢合作) ( 四级(中级)) 信誉:100 2005-8-16 12:09:31 得分:2
?


第一题也不过是注意一下申请,释放空间,还有遍历链表时的效率就够了!
Top
回复人:lesky(Fantasia 泫) ( 一级(初级)) 信誉:100 2005-8-16 13:33:28 得分:20
?


我简单的写了一下第一个,贴在这格式有点乱,你把它复制到别处就好了。
main()函数是最后一个简单的测试之后留下的,没什么用。
整个程序测试过了,不过因为时间短,我只简单的实现了一下,算法基本没问题,但是需要修改,有很多不是很好的地方。
很垃圾的程序……不好意思……我只是个大一的学生而已……希望对你有帮助。如果有什么问题可以联系我,我再帮你看看。 QQ:407222680
顺便说一句……面试这样过了……没用……以后怎么办……


#define LENV sizeof(struct vege)
#define LENC sizeof(struct counter)
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>


struct vege
{
char name[10];
float weight;


struct vege *next;
};




struct counter
{
char name[10];


struct vege *vh;
struct counter *next;
};


struct vege* creat_vege(void)
{
struct vege *p = (struct vege*)malloc( LENV );


if ( p == NULL )
{
printf("Bad malloc\n");
exit(0);
}
p->weight = 0.0;
strcpy(p->name, "unnamed");
p->next = NULL;


return p;
}


struct counter* creat_counter(void)
{
struct counter*p = (struct counter*)malloc( LENC );


if ( p == NULL )
{
printf("Bad malloc\n");
exit(0);
}


p->next = NULL;
p->vh = NULL;
strcpy(p->name, "unnamed");


return p;
}


struct vege* insertv(struct vege *head, struct vege *objv)
{
struct vege *p0,*p1,*p2;


p1 = head;
p0 = objv;


if(head == NULL)
{
head = p0;
p0->next = NULL;
}
else
{
while((strcmp(p0->name, p1->name) == -1) && (p1->next != NULL))
{
p2 = p1;
p1 = p1->next;
}
if(strcmp(p0->name, p1->name) == 1)
{
if(head == p1)
{
head = p0;
}
else
{
p2->next=p0;
}
p0->next = p1;
}
else if(strcmp(p0->name, p1->name) ==0 )
{
p1->weight += p0->weight;
}
else
{
p1->next = p0;
p0->next = NULL;
}
}


return head;
}


struct counter* insertc(struct counter *head, struct counter *objc)
{


struct counter *p0,*p1,*p2;


p1 = head;
p0 = objc;


if(head == NULL)
{
head = p0;
p0->next = NULL;
}
else
{
while((strcmp(p0->name, p1->name) == -1) && (p1->next != NULL))
{
p2 = p1;
p1 = p1->next;
}
if(strcmp(p0->name, p1->name) == 1)
{
if(head == p1)
{
head = p0;
}
else
{
p2->next=p0;
}
p0->next = p1;
}
else if(strcmp(p0->name, p1->name) == 0)
{
struct vege* vp = p0->vh;


while(vp != NULL)
{
p1->vh = insertv(p1->vh, vp);
vp = vp->next;
}
}
else
{
p1->next = p0;
p0->next = NULL;
}
}


return(head);
}


struct counter* unite(struct counter *obj1, struct counter *obj2)
{
struct counter *head,*p1,*p2,*pt;


head = NULL;
p1 = obj1;
p2 = obj2;


while( p1 != NULL)
{
head = insertc(head, p1);
pt = p1;
p1 = p1->next;
}
while( p2 != NULL)
{
head = insertc(head, p2);
pt = p2;
p2 = p2->next;
}
obj1 = NULL;
obj2 = NULL;


return head;
}


void print(struct counter* head)
{
struct counter *p = head;
struct vege *v;
while(p != NULL )
{
printf("counter name: %s\n",p->name);
v = p->vh;
while( v!= NULL)
{
printf("vname: %s weight: %.1f\n",v->name,v->weight);
v = v->next;
}
p = p->next;
}
}


int main()
{
int i,j;


struct counter *ha = NULL;
struct counter *hb = NULL;
struct counter *p;
struct vege *pp;


for(i=0; i<2; i++)
{
p = creat_counter();


strcpy(p->name,"a");
for(j=0;j<1;j++)
{
pp = creat_vege();
strcpy(pp->name, "vege1");
pp->weight = 10.1;
p->vh = insertv(p->vh, pp);
}
if ( i==0 )
ha = insertc(ha, p);
else
hb = insertc(hb, p);
}
p = unite(ha,hb);
print(p);


system("PAUSE");
return 0;
}
Top
回复人:lesky(Fantasia 泫) ( 一级(初级)) 信誉:100 2005-8-16 13:37:57 得分:1
?


伤心了,ACM什么时候有第二题这种垃圾T了……脑筋急转弯……
Top
回复人:lxinxuan(林子) ( 一级(初级)) 信誉:100 2005-8-16 15:36:03 得分:0
?


楼上的说ACM什么意思啊?
谢谢大家的回复啊,我会告诉我同学谢谢你们的,哈哈......
Top
回复人:VivianSnow(Phoenix) ( 一级(初级)) 信誉:100 2005-8-16 21:21:04 得分:0
?


那只是同济大学的一个在线提交程序题库而已,不是acm题啊,acm出这种题````那就````天下大乱啦``
Top
回复人:lxinxuan(林子) ( 一级(初级)) 信誉:100 2005-8-17 8:41:29 得分:0
?


我们公司两个同济牛人啊...带我的小组长就是,西西,偷着乐...
Top
回复人:ruiding(瑞丁) ( 一级(初级)) 信誉:100 2005-8-17 10:33:25 得分:0
?


关注...............
Top


该问题已经结贴 ,得分记录: Flood1984 (20)、 VivianSnow (5)、 smstone (2)、 lbing7 (2)、 lesky (20)、 lesky (1)、




15.
主  题: 面试题,测试链表中是否有环路?
作  者: silentspring (Crush_Japan)
等  级:
信 誉 值: 100
所属论坛: C/C++ C++ 语言
问题点数: 20
回复次数: 15
发表时间: 2005-8-15 10:12:37




how to test a linklist might be a circle???


大约就是这个样子了,记不起来了,如果以前有人问过,麻烦给个网址


请问这个东东有什么好的解决方法吗,差的偶会
回复人:robinzsy() ( 二级(初级)) 信誉:100 2005-8-15 10:19:36 得分:20
?


用2个游标进行遍历,一个步长为2,先出发;一个步长为1,后出发,如果后出发的游标能追上前面的游标,则存在环。
Top
回复人:rickstar(甜甜的薄荷糖) ( 一级(初级)) 信誉:100 2005-8-15 10:26:18 得分:0
?


我一直不明白,怎么判断后来的指针是否超过前面的指针???
Top
回复人:ruiding(瑞丁) ( 一级(初级)) 信誉:100 2005-8-15 10:49:32 得分:0
?




先定义两个链表指针:
pointer1=head;


pointer2=head->next->next;


然后循环比较,如果有回路 返回1 如果没有 返回0


while(pointer1!=pointer2)


{ pointer1=pointer1->next;


pointer2=pointer2->next->next;
}


if(NULL==pointer1)


return 0;


else


return 1;


我很菜,瞎写的,还请高手来指点......


Top
回复人:sankt(黄景天) ( 二级(初级)) 信誉:100 2005-8-15 10:53:55 得分:0
?


up
Top
回复人:James_ht(Erik) ( 一级(初级)) 信誉:100 2005-8-15 13:00:39 得分:0
?


判断是不是成环


Top
回复人:masterz(www.fruitfruit.com) ( 五星(高级)) 信誉:100 2005-8-15 13:10:15 得分:0
?


建议你再复习一下数据结构,你就算知道了这个问题的答案,还会有其他问题等你的
Top
回复人:improgrammer(无忌) ( 三级(初级)) 信誉:100 2005-8-15 13:16:33 得分:0
?


#include <map>
bool test_cycle(Node *p)
{
map<unsigned,int> m;
while (p)
{
if (m[(unsigned)p] == 100)
return true;
m[(unsigned)p]=100;
p = p->next;
}
return false;
}


Top
回复人:jxw111(喜笑颜开) ( 一级(初级)) 信誉:100 2005-8-16 9:14:08 得分:0
?


学习
Top
回复人:NEPTUNE211(亦木) ( 一级(初级)) 信誉:100 2005-8-16 9:59:26 得分:0
?


good good study , day day up !
Top
回复人:Roaming_Sheep(Roaming Sheep) ( 四级(中级)) 信誉:100 2005-8-16 10:37:11 得分:0
?


#include <map>
bool test_cycle(Node *p)
{
map<unsigned,int> m;
while (p)
{
if (m[(unsigned)p] == 100)
return true;
m[(unsigned)p]=100;
p = p->next;
}
return false;
}
————————————————————————
空间和时间代价都太大了
Top
回复人:On_Quiet_Night(再做一次楊過) ( 一级(初级)) 信誉:100 2005-8-16 11:48:30 得分:0
?


對鏈表進行遍厲就可以了,數據結構上多的是這樣的算法
Top
回复人:VivianSnow() ( 一级(初级)) 信誉:100 2005-8-16 11:54:51 得分:0
?


给节点多加一个值boo,类型为bool,初始值为false,代表是否访问过。


链表遍历的时候,如果发现有节点的boo==true,那么就有环
否则,对于节点,进行语句boo=true。
Top
回复人:LoveCreatesBeauty(爱产生美) ( 二级(初级)) 信誉:106 2005-8-16 13:55:12 得分:0
?


Oh, masterz 史前人物啊
Top
回复人:graymans(yoyo) ( 一级(初级)) 信誉:100 2005-08-16 14:36:00 得分:0
?
又学到一招!!谢谢!!
Top
回复人:improgrammer(无忌) ( 三级(初级)) 信誉:100 2005-08-16 14:51:00 得分:0
?
综合以上讨论,有三种方法:
1、追赶法;如 robinzsy。
2、外部记录法;如improgrammer。
3、内部记录法(打记号);如VivianSnow。
楼主斟酌选用。
Top


该问题已经结贴 ,得分记录: robinzsy (20)、


16.
主  题: 外企几道面试题高分求解
作  者: fesco (fesco)
等  级:
信 誉 值: 100
所属论坛: C/C++ C++ 语言
问题点数: 100
回复次数: 4
发表时间: 2005-8-9 21:48:33




1.如何判定两条线段是否相交?(可以写成伪代码)
2。一堆数在一个集合中,总共2n个,问如何将这些数分成A,B两分,每分n个,要求A中的数均小于B中的数,需要考虑时间复杂度,答案是 求中位数,时间为O(n),请牛人解释一下。谢谢




回复人:LoveYouJustOneDay(哈哈) ( 二级(初级)) 信誉:100 2005-8-9 22:12:44 得分:100
?


利用对手论证法证明中位数问题的比较次数下界


作者:starfish 时间:2002-01-05 11:59 出处:互联网 责编:chinaitpower


摘要:利用对手论证法证明中位数问题的比较次数下界




5个数通过6次比较求中位数的方法如下:


5 个数之间的大小关系构成的一个树形图T。T中的一个结点代表一个数,而一条边代表它所关联的两个数的大小关系,T的根就是中位数。显然T中的一条边要由一次比赛来确定。在下面的图中,如果x大于y,则节点x在节点y的上方且x和y有一条边相连。另外,*表示一般的数,o表示下一次即将进行比较的两个数。


第1步,先任取两个数比较,结果为:


*
|
* o o *


第2步,再取另外两个数比较,结果为:


o o
| |
* * *


第3步,按照上图比较其中两个标记为o的数,比较结果只有一种情况:


*
/ \
* o
|
* o


第4步,按照上图比较其中两个标记为o的数,比较结果有两种情况:


* o *
/ \ / / \
o * o o
| | |
* * *


第5步,按照上图比较其中两个标记为o的数,比较结果有两种情况:


* * *
/ \ / \ /
/ \/ \ /
| /\ | /
| / \ | *
| / \ | | \
|/ \| | \
o o | \
| o o
| |
| |
* *


第6步,按照上图比较其中两个标记为o的数,比较结果有两种情况:




* * * * * *
\ / \ / | |
x x * *
| / \ | |
* * * x x
| | / \
* * * *
|
*


其中的x就是中位数。




事实上,可以证明:对于n个数求中位数,至少需要3(n-1)/2次比较,并且存在一个O(n)次比较的算法。


下面介绍如何利用对手论证方法来证明中位数问题的比较次数下界。


首先介绍“对手论证(Adversary Argument)”方法。


若用P表示所讨论的问题,I表示问题的输入,A表示求解问题P的基于比较运算的算法T(A,I)表示对于输入I算法A的计算时间复杂性,那么,函数
U(n)=min{max{T(A,I)}, for each I}, for each A,
是问题P当输入的大小为n时在最坏情况下的最好下界。它是问题所固有的。


问题P的这个最好下界通常很难按其定义计算得到,因为对于一个具体的A,要得到
max{T(A,I)}, for each I
就是一件很难的事,更何况对于一切的A。因此,人们往往不去精确地求U(n),而是退而求其次,即找一个f(n),它不大于U(n)但尽量地接近于U(n),使f(n)成为问题P的一个好下界。








Top
回复人:LoveYouJustOneDay(哈哈) ( 二级(初级)) 信誉:100 2005-8-9 22:16:06 得分:0
?


请不要发表可能给我们带来伤害的言论,谢谢配合




什么垃圾论坛啊
连个学术论文都紧张成这样
不发了


Top
回复人:LoveYouJustOneDay(哈哈) ( 二级(初级)) 信誉:100 2005-8-9 22:16:24 得分:0
?


http://www.chinaitpower.net/A/2002-01-05/10026.html
Top
回复人:wiali(维埃里) ( 一级(初级)) 信誉:99 2005-8-10 1:28:22 得分:0
?


我靠,又是海星写的,无处不在啊!
Top


该问题已经结贴 ,得分记录: LoveYouJustOneDay (100)、


17.
主  题: 面试题,谢谢大家看看!!
作  者: smartqu ()
等  级:
信 誉 值: 100
所属论坛: C/C++ 新手乐园
问题点数: 50
回复次数: 29
发表时间: 2005-7-30 16:33:27




编写一个函数,作用是把一个char组成的字符串循环又移n个。


比如原来是


abcdefghi


如果n=2,移位后应该是


hiabcdefg


函数头是这样的:


void LoopMove(char * pStr,int steps)
{
//请填充...
//pStr是指向以'\0'结尾的字符串的指针,
//steps是要求移动的n。
}
请路过的帮忙看看提供一下代码,小弟刚学C


回复人:smartqu() ( 一级(初级)) 信誉:100 2005-7-30 16:34:27 得分:0
?


顶一下
Top
回复人:ljp_0913(霹雳贝贝) ( 一级(初级)) 信誉:100 2005-7-30 17:03:06 得分:3
?


#include<stdio.h>
#include<string.h>
void LoopMove(char *pStr,int steps)
{
int i;


int strlen;
while(*pStr)


strlen++;
for(i=strlen-1;i>=strlen-n;i--)
*(pStr+(strlen-1-i))=*(pStr+i);
for(i=0;i<strlen-n;i++)
*(pStr+i+n)=*(pStr+i);
return pStr;
}
main()
{
char *str="abcdefghi";
LoopMove(str,2);
printf("%s",str);
}
}
Top
回复人:jixingzhong(瞌睡虫) ( 五级(中级)) 信誉:100 2005-7-30 17:16:58 得分:2
?


void LoopMove(char * pStr,int steps)
{
char temp[20],ch;
int i,counts;
strcpy (temp,pStr);
for (counts=0; counts<steps; counts++)
{
i = 0;
ch = temp[0];
while (temp[i+1]!='\0')
{
temp[i] = temp[i+1];
i++;
}
temp[i] = ch;
}


printf("the start string is :\n");
puts(pStr);


printf("\n");


printf("the end string is :\n");
puts(temp);
}










main()
{
int n;
char p[]="abcdefghi";
printf("Please enter the num :\n");
scanf("%d",&n);
LoopMove(p,n);
getch();


}
Top
回复人:jixingzhong(瞌睡虫) ( 五级(中级)) 信誉:100 2005-7-30 17:20:30 得分:0
?





转反了...


我改一下...
Top
回复人:llf_hust() ( 五级(中级)) 信誉:100 2005-7-30 17:24:52 得分:3
?


#include<stdio.h>
#include<ctype.h>
#include<string.h>
void LoopMove(char *pStr,int steps)
{
int i, Len,tmp;
char s[20];
Len = strlen(pStr);
for (i=0; i<Len; i++)
{
tmp = Len-steps+i;
s[i] = pStr[tmp%Len];
}
s[i] = '\0';
printf("%s\n",s);
}


int main()
{
char s[]="abcdefghi";
LoopMove(s,2);
return 0;
}


Top
回复人:xufangrui(独孤风清) ( 一级(初级)) 信誉:100 2005-7-30 17:24:58 得分:3
?


呵呵,这些东西.思想都知道的.只要你静下心来,很容易做出来的.为什么要问别人呢?
只是我的建议,希望你不要见怪!!!呵呵
Top
回复人:jixingzhong(瞌睡虫) ( 五级(中级)) 信誉:100 2005-7-30 17:27:48 得分:3
?


void LoopMove(char * pStr,int steps)
{
char temp[20],ch;
int i,counts;
strcpy (temp,pStr);


for (counts=0; counts<steps; counts++)
{
i = strlen(temp);
i--; //注意数组下标,要减1 才正确
ch = temp[i];


while (i>0)
{
temp[i] = temp[i-1];
i--;
}


temp[0] = ch;
}


printf("the start string is :\n");
puts(pStr);


printf("\n");


printf("the end string is :\n");
puts(temp);
}










main()
{
int n;
char p[]="abcdefghi";
printf("Please enter the num :\n");
scanf("%d",&n);
LoopMove(p,n);
getch();


}






呵呵


两个程序思想是一样的


就是转的方向不一样拉
Top
回复人:ruiding(瑞丁) ( 一级(初级)) 信誉:100 2005-7-30 17:42:29 得分:3
?


#include<stdio.h>


#include<string.h>


#include<stdlib.h>


#include<malloc.h>




void LoopMove(char * pStr,int steps)
{


int i;


int j;


char * mStr;




j=strlen(pStr)+1;


mStr=(char*)malloc(sizeof(char)*j);




strcpy(mStr,pStr);


for(i=0;i<j;i++)


{
pStr[i]=mStr[(i+steps)%j];
}


free(mStr);


}




int main(void)


{


int i;


char *pStr;




scanf("%d",&i);


pStr="asdfghjk";


LoopMove(pStr, i);


printf("%s\n",pStr );


return 0;


}


我写了这么一个程序,但是当输入 2 后 会出现“0x0040b7e9”指令引用的"0x00420020"的内存。该内存不能为"written"请问这是什么错误,是不是内存泄漏.(知道问题很菜,见笑了).
Top
回复人:llf_hust() ( 五级(中级)) 信誉:100 2005-7-30 17:46:19 得分:3
?


#include<stdio.h>


#include<string.h>


#include<stdlib.h>


#include<malloc.h>




void LoopMove(char * pStr,int steps)
{


int i;


int j;


char * mStr;




j=strlen(pStr)+1;


mStr=(char*)malloc(sizeof(char)*j);




strcpy(mStr,pStr);


for(i=0;i<j;i++)


{
pStr[i]=mStr[(i+steps)%j];
}


free(mStr);


}




int main(void)


{


int i;


char pStr[20]="asdfghjk";;




scanf("%d",&i);


/*pStr="asdfghjk"; */


LoopMove(pStr, i);


printf("%s\n",pStr );


return 0;


}
/* 改成这样就没有报那样的错误了 */
Top
回复人:foochow(恰似你的温柔) ( 一星(中级)) 信誉:100 2005-7-30 17:46:25 得分:3
?


#include<iostream>
#include<cstring>
using namespace std;
void LoopMove(char*ps,int n)
{
int k=strlen(ps);
char*tp=new char[k];
memcpy(tp,ps+k-n,n);
memcpy(tp+n,ps,k-n);
memcpy(ps,tp,k);
ps[k]=0;
delete [] tp;
}
int main()
{
char temp[]="abcdefghi";
LoopMove(temp,2);
cout<<temp<<endl;
return 0;
}


Top
回复人:artsssss() ( 一级(初级)) 信誉:100 2005-7-30 17:48:51 得分:0
?


楼主的题目pStrpStr是指向以'\0'结尾的字符串的指针!!!!
Top
回复人:qifa() ( 二级(初级)) 信誉:100 2005-7-30 17:55:19 得分:3
?


void LoopMove(char * pStr,int steps)
{
//请填充...
//pStr是指向以'\0'结尾的字符串的指针,
//steps是要求移动的n。
int len = strlen(pStr);
int i;
int j = 0;
char *pTemp = (char *)malloc(len+1);
steps %= len;
if(pTemp == NULL) return ;
for(i=steps; pStr[i] ;i++)
{
pTemp[j] = pStr[i];
j++;
}
for(i=0;i<steps;i++)
{
pTemp[j] = pStr[i];
j++;
}
pTemp[j]=0;
strcpy(pStr,pTemp);
free(pTemp);
}
Top
回复人:qifa() ( 二级(初级)) 信誉:100 2005-7-30 17:57:53 得分:0
?


各位很多都没有考虑steps大于字符串长度的情况!!
Top
回复人:ruiding(瑞丁) ( 一级(初级)) 信誉:100 2005-7-30 18:06:20 得分:0
?


to llf_hust()


我试了一下 还是不对,当输入5 时 输出的是 hjk


还有我想问一下 出现“0x0040b7e9”指令引用的"0x00420020"的内存。该内存不能为"written"


折中错误是怎么引起的.
Top
回复人:nciml() ( 一级(初级)) 信誉:100 2005-7-30 18:31:24 得分:0
?


我也想想
Top
回复人:foochow(恰似你的温柔) ( 一星(中级)) 信誉:100 2005-7-30 18:33:04 得分:3
?


#include<iostream>
#include<cstring>
using namespace std;
void LoopMove(char*ps,int n)
{
n%=strlen(ps);
int k=strlen(ps);
char*tp=new char[k];
memcpy(tp,ps+k-n,n);
memcpy(tp+n,ps,k-n);
memcpy(ps,tp,k);
ps[k]=0;
delete [] tp;
}
int main()
{
char temp[]="abcdefghi";
LoopMove(temp,9);
cout<<temp<<endl;
return 0;
}
Top
回复人:apollon_hhy(apollon_hhy) ( 一级(初级)) 信誉:100 2005-7-30 18:42:47 得分:3
?


#include <iostream.h>
#include <string.h>


void LoopMove(char * pStr, int steps)
{ int len = strlen(pStr);
char temp; // 用于存放最后一个字符
for(int j = 0; j < steps ; ++j)
{
temp = *(pStr + len - 1);
for(int i = len - 2 ; i >= 0 ; --i)
{
*(pStr + i + 1) = *(pStr + i); // 从第二个字符开始依次后移
}
*(pStr) = temp; // 把最后一个字符放置到第一个字符位置
}
}
Top
回复人:apollon_hhy(apollon_hhy) ( 一级(初级)) 信誉:100 2005-7-30 18:43:43 得分:0
?


忘记发main() 了 不好意思 :-)
void main ( )
{ char str[] = "abcdefghi";
int times = 2, len = strlen(str);
LoopMove(str, times);
for(int k = 0; k < len; ++k)
cout << *(str + k);
cout << endl;
}
Top
回复人:llf_hust() ( 五级(中级)) 信誉:100 2005-7-30 18:50:51 得分:3
?


to llf_hust()


我试了一下 还是不对,当输入5 时 输出的是 hjk


还有我想问一下 出现“0x0040b7e9”指令引用的"0x00420020"的内存。该内存不能为"written"


折中错误是怎么引起的.
/* 那就是你程序写得有问题了 ,仔细检查一下你的程序 */
Top
回复人:nciml() ( 一级(初级)) 信誉:100 2005-7-30 18:51:40 得分:1
?


法1:在LoopMove中设个字符数组,自己想按什么顺序排放就按什么顺序排放


法2:将最后一个字符放在char array_end 中,把前面的字符向后顺移,再把array_end赋值给*pStr
即array[0] 重复前面的步骤n次


还有其他的方法但没这简单
Top
回复人:antijpn(antijpn) ( 一星(中级)) 信誉:100 2005-7-30 20:17:49 得分:0
?


直接求代码,转新手乐园
Top
回复人:zsx123(我要活下去) ( 二级(初级)) 信誉:100 2005-7-31 10:38:34 得分:2
?


各位很多都没有考虑steps大于字符串长度的情况!!




#include <iostream.h>
#include <string.h>
void LoopMove(char *pstr,int steps)
{
int size=strlen(pstr);
steps%=size;
for(int i=0;i<steps;i++)
{
char temp=*(pstr+size-1);
for(int j=size-1;j>=1;j--)
{
*(pstr+j)=*(pstr+j-1);
}
*pstr=temp;
}
return;
}


void main(void)
{
char pstr[]="abcdefg";


LoopMove(pstr,8);
cout<<pstr;
}


Top
回复人:cyblueboy83(爱情白痴—电脑迷) ( 一级(初级)) 信誉:100 2005-7-31 11:55:00 得分:2
?




#include "stdafx.h"
#include "stdio.h"
#include<string.h>




void LoopMove(char *pStr,int steps)
{
int i, Len,tmp;
char s[20];
Len = strlen(pStr);
for (i=0; i<Len; i++)
{
tmp = Len-steps+i;
s[i] = pStr[tmp%Len];
}
s[i] = '\0';
printf("%s\n",s);
}


int main(int argc, char* argv[])
{
char s[]="abcdefghi";
LoopMove(s,2);
return 0;
}
Top
回复人:rejacky(任) ( 一级(初级)) 信誉:100 2005-7-31 13:24:11 得分:1
?


e
Top
回复人:rejacky(任) ( 一级(初级)) 信誉:100 2005-7-31 13:24:27 得分:2
?


#include <iostream.h>
#include <string.h>
//哈哈,这个就不用判断是否超长了
void moveOne(char *pstr) //把最后一个字符放到第一个字符前
{
int size = strlen(pstr);
char temp = *(pstr + size -1);
for(int j = size-1; j>=1; j--)
{
*(pstr+j) = *(pstr+j-1);
}
*pstr = temp;
}


void LoopMove(char *pstr,int steps)
{
for(int i =1; i<= steps; i++)
{
moveOne(pstr);
}
}


void main(void)
{
char pstr[]="abcdefg";
LoopMove(pstr,4);
cout<<pstr<<endl;
}
Top
回复人:xiaoxiangqing(肖祥清) ( 一级(初级)) 信誉:100 2005-7-31 15:23:55 得分:2
?


#include <string.h>
#include <stdio.h>


void LoopMove(char *Pstr,int steps)
{
char *Dstr;
int len=strlen(Pstr),i=-1,j=0;


Dstr=new char(len+1);


while(++i<len-steps)
Dstr[steps+i]=Pstr[i];


while(i<len)
Dstr[j++]=Pstr[i++];


strcpy(Pstr,Dstr);


delete Dstr;


}


int main(int argc, char* argv[])
{
char *str="abcdefghi";


printf("str=%s\n",str);


LoopMove(str,2);
printf("str=%s\n",str);
return 0;
}
Top
回复人:gofire(床前太阳光,疑是鸡蛋汤;) ( 一级(初级)) 信誉:100 2005-7-31 15:51:15 得分:2
?


上面的算法都太浪费cpu了,尤其是在字符串长,右移位数多的情况下。
换个思路,如果右移3位,那么
0-3-6-9 ...
1-4-7-...
2-5-8...
这个样子写的话,算法的量就是字符串的长度了,无论右移多少位。


void LoopMove(char *pstr,int steps)
{
int size=strlen(pstr);
steps%=size;
for(int i=0;i<steps;i++)
{
char temp=*(pstr+size-1-i);


for(int j=size-1-i;j>=steps;j-=steps)
{
*(pstr+j) = *(pstr+j-steps);
}


*(pstr+j)=temp;
}
return;
}


void main(void)
{
char pstr[]="abcdefghijklmnopqrstuvwxyz";


LoopMove(pstr,28);
cout<<pstr;
}


Top
回复人:gofire(床前太阳光,疑是鸡蛋汤;) ( 一级(初级)) 信誉:100 2005-7-31 16:05:47 得分:1
?


等一下,我的程序没有考虑周全,有bug存在
Top
回复人:gofire(床前太阳光,疑是鸡蛋汤;) ( 一级(初级)) 信誉:100 2005-7-31 16:17:12 得分:2
?


如果size能被steps(mod过后)整除,那么上面就是正确的
如果size不能被整除,那么就是连在一起的了
如:0~9 共10个数字,右移动3位
0-3-6-9-2-5-8-1-4-7
唉,懒得动手改程序了,反正思路就是这样了,加个整除判断,分别考虑一下。
看代价了,如果字符串短就没有必要写这个样子的,一步步移的代码比较简单。




Top


该问题已经结贴 ,得分记录: ljp_0913 (3)、 jixingzhong (2)、 llf_hust (3)、 xufangrui (3)、 jixingzhong (3)、 ruiding (3)、 llf_hust (3)、 foochow (3)、 qifa (3)、 foochow (3)、 apollon_hhy (3)、 llf_hust (3)、 nciml (1)、 zsx123 (2)、 cyblueboy83 (2)、 rejacky (1)、 rejacky (2)、 xiaoxiangqing (2)、 gofire (2)、 gofire (1)、 gofire (2)、


18.
主  题: 面试题
作  者: fujingn188 ()
等  级:
信 誉 值: 100
所属论坛: C/C++ 新手乐园
问题点数: 0
回复次数: 23
发表时间: 2005-7-12 18:50:21




1.char * p1,int * p2,long * p3,(void*)p1=(void*)p2=(void*)p3=(void*)4求p1++,p2++,p3++?
2.宏定义的函数跟一般函数有什么异同,写出两个宏定义容易出错的地方?
3.C语言中未分配地址的指针32位指针的值是多少?
4.float x,y x=y=123,则(x==y)的值是多少?
5.把S2中的字符接到S1后面
void strcat(char * s1,char * s2)
{
while(*s1!='\0')
______________;
for(;___;s1++,s2++)
}
回复人:James_ht(Erik) ( 一级(初级)) 信誉:100 2005-7-12 19:29:08 得分:0
?


写出两个宏定义容易出错的地方?
第二个:#define DIV(a,b) a/b
int arg1 = 7,arg2 = 5;
float value;
value = (float)(DIV(arg1*arg2,arg1-arg2)/2);
Top
回复人:supersuperguo(Alex Guo) ( 一级(初级)) 信誉:100 2005-7-12 19:36:15 得分:0
?


1. p1为5, p2为8(32位系统)或6(16位系统),p3为8
2. 宏定义函数和一般使用方法类似,但是宏定义函数是立即解释的,无堆栈的,像lisp语言一样在源代码级上替换参数;一般函数有堆栈,在表达式的值的级上替换参数
易错1:
#define sqr(x) x*x /* 此时如果调用sqr(1+2)时变成1+2*1+2即5,不是预期的9
易错2:
#define sqr(x) x*x /* 此时若有变量x=1,则调用sqr(++x)时变成++x*++x即6,而不是预期的4 */
3. NULL
4. 非0
5. s1++ *s1=*s2
Top
回复人:lalalalala5(X语言) ( 一级(初级)) 信誉:100 2005-7-12 19:58:52 得分:0
?


楼上的历害!赞
Top
回复人:fujingn188() ( 一级(初级)) 信誉:100 2005-7-12 20:31:37 得分:0
?


第一题不懂谁能帮我解释下?
Top
回复人:surfer2888() ( 一级(初级)) 信誉:100 2005-7-12 21:24:33 得分:0
?


很简单阿,指针的计算会自动考虑指针的类型的,例如char是一位的,++则指针的地址指向加1


Top
回复人:leonatcs(LeonKennedy)(每天逛一逛csdn,有益身心健康。) ( 一级(初级)) 信誉:100 2005-7-12 21:40:25 得分:0
?


解释:
设有T *型的指针p,
则p++(也就是p+1)就等于 p + sizeof(T)
比如: char * p;
p++; //值就是p + sizeof(char)




Top
回复人:zhulianggen(宁无) ( 一级(初级)) 信誉:100 2005-7-12 23:20:34 得分:0
?


1.char * p1,int * p2,long * p3,(void*)p1=(void*)p2=(void*)p3=(void*)4求p1++,p2++,p3++?


p1,p2,p3的值是地址值,但是初始地值未知,怎么解答?
而且,p1++,p2++,p3++是否是顺序求解的?
也就是象如下语句:
p1++;
p2++;
p3++;
则,假设初始地址是p0
p1=p0+1,p2=p0+1+4,p3=p0+1+4+8


2.宏定义的函数跟一般函数有什么异同,写出两个宏定义容易出错的地方?


宏定义函数是立即解释的,无堆栈的,;一般函数有堆栈,在表达式的值的级上替换参数
易错1:
#define sqr(x) x*x /* 此时如果调用sqr(1+2)时变成1+2*1+2即5,不是预期的9
易错2:
#define sqr(x) x*x /* 此时若有变量x=1,则调用sqr(++x)时变成++x*++x即6,而不是预期的


3.C语言中未分配地址的指针32位指针的值是多少?


0xcccc


4.float x,y x=y=123,则(x==y)的值是多少?


float x,y x=y=123语句有问题,应该为
float x,y;
x=y=123;
再判断,如果这样则为true




5.把S2中的字符接到S1后面
void strcat(char * s1,char * s2)
{
while(*s1!='\0')
______________;
for(;___;s1++,s2++)
}


s1++
(*s1=*s2)!='\0'


Top
回复人:mxtah(mxtah) ( 一级(初级)) 信誉:100 2005-7-13 15:34:39 得分:0
?


void strcat(char * s1,char * s2)
{
while(*s1!='\0')
______________;
for(;___;s1++,s2++)
}
=================================
我觉得最好把char* s1,char* s2改成:
char s1[],char s2[]
虽然两者是相等的,但是要主意的是在写main函数时,应该写成:
char s1[] = "abc";
char s2[] = "dee";
Top
回复人:yesiloveyou(﹀Tree) ( 二级(初级)) 信誉:90 2005-7-13 16:09:47 得分:0
?


为什么我把上面zhulianggen(宁无) 填的程序写了下,会出错?大吓们帮我看看哪里写错了?
#include <iostream>
using namespace std;


void strcat(char *str1,char *str2)
{
while(*str1!='\0')
str1++;
for(;(*str1=*str2)!='\0';str1++,str2++);
}


int main ()
{
char *str1,*str2;
str1="abc";
str2="def";
strcat(str1,str2);
cout<<str1<<" "<<str2<<endl;
return 0;
}
Top
回复人:kernelxu(残眉) ( 一级(初级)) 信誉:100 2005-7-13 16:31:09 得分:0
?


zhulianggen(宁无) 填的第5个程序是错误的!
应该是
s1++
*s1=*s2
而不是
s1++
(*s1=*s2)!='\0'
因为如果在后加了!='\0'后会使得s1中存储的一系列字符没了'\0'作为结束符,以后就不能对s1进行
字符串的操作了。
第1题中
char * p1,int * p2,long * p3,(void*)p1=(void*)p2=(void*)p3=(void*)4
4这个常量地址即是p1、p2、p3所指向的地址。
(void*)p1=(void*)p2=(void*)p3=(void*)4在求p1++,p2++,p3++之前操作,相当于对各指针赋了初值
基本同意二楼的。
只是第3题不太确定,在VC6.0中好像是0Xcccccccc,其他不知道,请高人告知。




Top
回复人:llf_hust() ( 五级(中级)) 信誉:100 2005-7-13 16:41:44 得分:0
?


#include <iostream>
using namespace std;


void strcat(char *str1,char *str2)
{
while(*str1!='\0')
str1++;
for(;(*str1=*str2)!='\0';str1++,str2++);
}


int main ()
{
char str1[]="abc",str2[]="def";
strcat(str1,str2);
cout<<str1<<" "<<str2<<endl;
return 0;
}


Top
回复人:yinzhi95(燕南飞) ( 一级(初级)) 信誉:100 2005-7-13 16:51:26 得分:0
?


好贴!
Top
回复人:nuaa3(alan) ( 一级(初级)) 信誉:100 2005-7-13 19:57:46 得分:0
?


我不同意你说的 (*s1=*s2)!='\0' 与 *s1=*s2 都是可以的。 *s1=*s2 只不过隐藏了 判断里面。
===========
kernelxu() ( ) 信誉:100 说道:
zhulianggen(宁无) 填的第5个程序是错误的!
应该是
s1++
*s1=*s2
而不是
s1++
(*s1=*s2)!='\0'
因为如果在后加了!='\0'后会使得s1中存储的一系列字符没了'\0'作为结束符,以后就不能对s1进行
字符串的操作了。
第1题中
char * p1,int * p2,long * p3,(void*)p1=(void*)p2=(void*)p3=(void*)4
4这个常量地址即是p1、p2、p3所指向的地址。
(void*)p1=(void*)p2=(void*)p3=(void*)4在求p1++,p2++,p3++之前操作,相当于对各指针赋了初值
基本同意二楼的。
只是第3题不太确定,在VC6.0中好像是0Xcccccccc,其他不知道,请高人告知。
Top
回复人:wenwen227(过河卒) ( 一级(初级)) 信誉:100 2005-7-13 22:51:01 得分:0
?


第一题
指针的运算,指针的加减是和他的类型有关的,即:
设有T *型的指针p,
则p++(也就是p+1)就等于 p + sizeof(T)
但是本题后面的(void*)p1=(void*)p2=(void*)p3=(void*)4
VC++7.0下编译错误
一个指针变量所指向的类型定义后是不能改的,
而void*只是代表指向一块内存,具体什么类型
看你怎么转换,但是若
void* p1 ="111";
p1++;
提示:“void *” : 未知的大小
所以void*不能进行指针运算
他的内容具体含义看转换
char * c= (char *)p1;
那就是字符
int * i= (int *)p1;
那就是整型
第二题
2.宏定义的函数跟一般函数有什么异同,写出两个宏定义容易出错的地方?
宏只是简单代替,所以会很危险
第三题
只知道MicroSoft的VC++下是0xcccccccc
第四题
4.float x,y x=y=123,则(x==y)的值是多少?
我测试是true
虽然是浮点数,但编译时,x,y内存中的内容是一样的
第五题
5.把S2中的字符接到S1后面
void strcat(char * s1,char * s2)
{
while(*s1!='\0')
______________;
for(;___;s1++,s2++)
}
s1++
我个人认为这个比较好,我在vc++7.0下测试了正常
(*s1 = *s2) != '\0'




望高手指点!!!!!!!!!!!!!!!!1


Top
回复人:myhouwei(myhouwei) ( 一级(初级)) 信誉:100 2005-7-13 23:52:37 得分:0
?


1.char * p1,int * p2,long * p3,(void*)p1=(void*)p2=(void*)p3=(void*)4求p1++,p2++,p3++?


5 8 8


s1++
(*s1=*s2)!='\0'
加了小括号了,就先做付值,再判断,所以当测试为'\0'时,\0已经付给S1了,所以它是完整的字符串,可以进行字符串操作
Top
回复人:kernelxu(残眉) ( 一级(初级)) 信誉:100 2005-7-14 10:55:27 得分:0
?


其实*s1=*s2和(*s1=*s2)!='\0'是一样的,反而觉得(*s1=*s2)!='\0'更清晰明了,风格更好。
谢谢nuaa3(alan)、 myhouwei(myhouwei)指出错误,对zhulianggen(宁无)表示歉意!
对于第3题还有话要说:
我在WIN2000+VC6.0环境下运行一下代码:
/***********************************************
*file name : float_accuracy.c
*description : x是float类型,什么情况下x!=x为真
*note : 若在判断x!=x前对x进行了修改,则
有可能使x!=x为真
*author : kernelxu
*resource : http://bbs.chinaunix.net/forum/
viewtopic.php?t=575049&show_type=
*date : 2005/07/10
***********************************************/


#include <stdio.h>


/**********************************************
*function name : main()
***********************************************/
int main(void)
{
float x = (float)1e-3;


x = x + 1;
//printf("HELLO WORLD!\n");
if (x != x)
{
printf("x is UNequal to x!!\n");
}
else
{
printf("x is equal to x!\n");
}


return 0;
}/*END OF main()*/
运行结果是:
x is UNequal to x!!
加上被注释的那一条后,结果为:
x is equal to x!


怀疑是VC6.0的BUG。
具体大家可看看:
http://bbs.chinaunix.net/forum/viewtopic.php?t=575049&show_type=


Top
回复人:Willpro(WillPro) ( 二级(初级)) 信誉:100 2005-7-14 12:00:53 得分:0
?


www.mark.com
Top
回复人:cy2005abc() ( 一级(初级)) 信誉:100 2005-7-14 12:34:09 得分:0
?


void strcat(char * s1,char * s2)
{
while(*s1!='\0')
s1++;
______________;
(*s1=*s2)
for(;___ ; s1++,s2++);
}


Top
回复人:whatsouta(某疯子) ( 二级(初级)) 信誉:100 2005-7-14 17:49:39 得分:0
?


所有答5 8 8 的,要答
4+sizeof(char)
4+sizeof(int)
4+sizeof(long)
Top
回复人:hj008(catch jjhou) ( 一级(初级)) 信誉:100 2005-7-14 20:56:06 得分:0
?


float 好象最好不要象上面的那样比吧.
Top
回复人:bestvanguard(yangqiao) ( 一级(初级)) 信誉:100 2005-7-29 10:21:01 得分:0
?


留名
Top
回复人:antijpn(antijpn) ( 一星(中级)) 信誉:100 2005-7-29 14:56:22 得分:0
?


和作业没两样……


转新手乐园
Top
回复人:xiaojun789(笑) ( 一级(初级)) 信誉:100 2005-07-30 20:43:00 得分:0
?




mark


19.
 
CSDN - 专家门诊 - C/C++ C++ 语言问题
回复 | 推荐 | 收藏 | 专题 | 公告 | 管理 | 关闭窗口
主  题: 一家外企的面试题目,欢迎讨论,来者有份
作  者: lu64 (路)
等  级:
信 誉 值: 100
所属论坛: C/C++ C++ 语言
问题点数: 100
回复次数: 123
发表时间: 2005-7-3 19:23:31




1、智能指针,com实现的原理,
2、printf()可变参数如何实现
3、标准模板库vector追加数据如何实现。是底层如何实现,不能用现有的东东。
4、还有,java的垃圾收集机制如何实现为什么?如果是你自己实现垃圾收集机制,如何实
现? 用什么数据结构。
5、二叉排序树和哈希表那个查找效率高,实用于pda 。
6、.net的底层实现机制。
8、还有迭代问题,什么问题用迭代,迭代在操作系统中如何实现的 。
9、如何交换两个变量,不能用中间变量。
10、c与c++ static函数的区别???
11、const 函数的作用,如何实现钩子函数。
12、两层容错技术怎么实现?
13、写出函数指针,函数返回指针,const指针,指向const的指针,指向const的const指针

14、函数调用如何实现,注意什么问题。
15、指针和引用的差别,
16、拷贝构造函数如何实现,什么情况下会用到。


回复人:yhbttfile(小兵) ( 二级(初级)) 信誉:100 2005-7-3 19:42:50 得分:0
?


它到底要什么人才?
有C++知识;有C知识(C与C++还是存在很大差别的);JAV知识,有COM知识;有.NET知识。
每个方面都需要花起码几年的时间才能成为专家,熟悉也要以月计算。
搞不懂其目的是什么。要招架构设计师?程序员?




Top
回复人:qfeng_zhao(一天到晚游泳的鱼) ( 三级(初级)) 信誉:100 2005-7-3 20:00:07 得分:0
?


无言
Top
回复人:yhbttfile(小兵) ( 二级(初级)) 信誉:100 2005-7-3 20:08:44 得分:0
?


1、智能指针,com实现的原理,
—— 如果是C++的智能指针,则主要是利用栈对象的有限作用域以及临时对象(有限作用域实现)析构函数释放内存。当然,智能指针还不指这些,还包括复制时可以修改源对象等。智能指针根据需求不同,设计也不同(COW技术,赋值即释放对象拥有权限,引用基数等)。这个主题可以将一本书。COM更复杂!MS的东西,一般都不想深入分析。


2、printf()可变参数如何实现
——利用...参数特性。就是说可以访问va_list(一般变量名为arglist)。参数列表中可以方任何C支持的对象类型。这是C语言的用法,C++中一定不要再使用该函数,否则就是一个安全漏洞,就等黑客攻击你的程序吧。


3、标准模板库vector追加数据如何实现。是底层如何实现,不能用现有的东东。
—— C++的STL东西。关键点是,在最佳对象前先判断预留的空间是否满足需求,如果不满足则根据分配策略,则另分配足够的空间(一般使用平方增加策略),复制以前的对象数组,然后把对象追加到尾部。如果任何一个操作环境失败,则至少保留原数组不受影响(异常安全保证策略)。


4、还有,java的垃圾收集机制如何实现为什么?如果是你自己实现垃圾收集机制,如何实
现? 用什么数据结构。
——JAVA是SUN的特有产品,本人只做了解,也不希望深究。其他高手讲解。


5、二叉排序树和哈希表那个查找效率高,实用于pda 。
——普遍来说,哈希表更快。可以找任何一个算法的书就可以知道他们的普通复杂度。


6、.net的底层实现机制。
——又是一个与具体公司相关的产品,没兴趣。


7、进程间通信如何实现。
——看是什么平台。UNIX可以通过信号、共享内存、SOCKET、共享文件、管道等。WINDOWS有消息、共享内存、SOCKET、共享文件、管道等。


8、还有迭代问题,什么问题用迭代,迭代在操作系统中如何实现的 。
——迭代器其实就是一个容器的访问代理类。迭代器跟操作系统存在什么关系呢?那他到底要问什么样的迭代器呢?


9、如何交换两个变量,不能用中间变量。
——你问问考官,两杯水,不使用空杯子,看他怎么交换。


10、c与c++ static函数的区别???
——这个问题的确没有关注过。


11、const 函数的作用,如何实现钩子函数。
——const 函数一般用于访问对象。钩子函数的使用一直都是一个引起争议的设计方法。目前,很多系统都有更好的替代方法。实现方法讲起来太罗嗦,还不如随便找一个例子看看。


12、两层容错技术怎么实现?
——太深奥。


实在太多了。大家继续哈。。。


Top
回复人:god_sun(孙大帅哥) ( 一级(初级)) 信誉:100 2005-7-3 20:13:41 得分:0
?


好恐怖的面试题,那个公司肯定是要北大青鸟毕业的,哈哈:)
Top
回复人:sdbtb(sdbtb) ( 一级(初级)) 信誉:100 2005-7-3 20:46:16 得分:0
?


成都MOTO实习生的笔试题。
Top
回复人:sdbtb(sdbtb) ( 一级(初级)) 信誉:100 2005-7-3 20:51:24 得分:0
?


9、如何交换两个变量,不能用中间变量。
void inplace_swap(int *x, int *y)
{
*x = *x &#710; *y; /* Step 1 */
*y = *x &#710; *y; /* Step 2 */
*x = *x &#710; *y; /* Step 3 */
}
Top
回复人:sdbtb(sdbtb) ( 一级(初级)) 信誉:100 2005-7-3 20:53:12 得分:0
?


上一个回复代码有些问题,修正一下。
9、如何交换两个变量,不能用中间变量。
void inplace_swap(int *x, int *y)
{
*x = *x ^ *y; /* Step 1 */
*y = *x ^ *y; /* Step 2 */
*x = *x ^ *y; /* Step 3 */
}


Top
回复人:parkforever(昵称) ( 一级(初级)) 信誉:100 2005-7-3 20:55:39 得分:0
?


9、如何交换两个变量,不能用中间变量。


a=a+b;
b=a-b;
a=a-b;
Top
回复人:YouYunnetyang(游云) ( 一级(初级)) 信誉:100 2005-7-3 20:56:05 得分:0
?


强!


就三个字!看 不懂!


*x = *x ^ *y; /* Step 1 */
*y = *x ^ *y; /* Step 2 */
*x = *x ^ *y; /* Step 3 */




解释一下先!
Top
回复人:yhbttfile(小兵) ( 二级(初级)) 信誉:100 2005-7-3 21:03:41 得分:0
?


这种交换法,可以运用到对象吗?




Top
回复人:du51(郁郁思扬) ( 五级(中级)) 信誉:100 2005-7-3 21:08:08 得分:0
?


16.拷贝构造一般用在以同类对象为参数的构造.
MyClass(MyClass &copy);
Top
回复人:du51(郁郁思扬) ( 五级(中级)) 信誉:100 2005-7-3 21:10:38 得分:0
?


2.我只知道C里面有一个隐性的万能转换,这个东西,有时候很方便,有时候害人.
再多就不会了.
Top
回复人:songsong33(拳击亚军) ( 二级(初级)) 信誉:100 2005-7-3 21:12:07 得分:0
?


恐怖
Top
回复人:mayingbao(浪客剑心) ( 一级(初级)) 信誉:100 2005-7-3 21:13:47 得分:0
?


9、如何交换两个变量,不能用中间变量。


a=a+b;
b=a-b;
a=a-b;






要问一点他到点要你哪方面精呀
问哪么多


Top
回复人:du51(郁郁思扬) ( 五级(中级)) 信誉:100 2005-7-3 21:19:52 得分:0
?


14、函数调用如何实现,注意什么问题。
想了半天,不知道如何实现.或者是不知道应该怎么说.注意问题道是知道一点.就是注意类型转换,以及返回值是否有效.当然了,相关的就多了.
15、指针和引用的差别,
指针操作的是被操作对象的地址.引用是对操作对象本身进行操作.


Top
回复人:firstdreamer(我不懂指针和OOP) ( 二级(初级)) 信誉:100 2005-7-3 21:21:34 得分:0
?


15.引用的一些规则如下:
(1)引用被创建的同时必须被初始化(指针则可以在任何时候被初始化)。
(2)不能有NULL 引用,引用必须与合法的存储单元关联(指针则可以是NULL)。
(3)一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变所指的对象)。
指针能够毫无约束地操作内存中的如何东西,
Top
回复人:foochow(恰似你的温柔) ( 五级(中级)) 信誉:100 2005-7-3 21:25:50 得分:0
?


呵呵,好多
Top
回复人:chinaamber(chinaamber) ( 一级(初级)) 信誉:100 2005-7-3 21:45:14 得分:0
?


问题4:JAVA在一对{}结束以后会自动释放其中定义的所有的对象。
问题11:object const objName = i;const object objName = i; const object const objName = i;
问题14:function(parameter1,parameter2...)注意参数的类型,数量。在有重载的函数的时候要尤其要注意。在不同的文件当中要注意是否能够直接使用,不申明不能使用。
问题15:指针可以直接指向一块空间,引用必须有数值。简单说引用是变量的用法,指针的本质。
问题16:好显示有一个专门的声明一下,同样构造时使用。呵呵
Top
回复人:sankt(黄景天) ( 二级(初级)) 信誉:100 2005-7-3 21:45:29 得分:0
?


不错
up
Top
回复人:yangbc(土豆块) ( 一级(初级)) 信誉:100 2005-7-3 22:04:21 得分:0
?


小兵你还太嫩了
Top
回复人:springmaster(清泉) ( 一级(初级)) 信誉:100 2005-7-3 22:05:40 得分:0
?


13、写出
函数指针 void (*Func)();
函数返回指针 void *Func();
const指针 const void *p;
指向const的指针 void const *p;
指向const的const指针 const void const *p;


Top
回复人:graymans(yoyo) ( 一级(初级)) 信誉:100 2005-7-3 22:25:59 得分:0
?


13.
const指针 const void *p;
指向const的指针 void * const p;
指向const的const指针 const void * const p;


Top
回复人:woodyong(woodyong) ( 一级(初级)) 信誉:100 2005-7-3 22:27:52 得分:0
?


const指针 void* const p;
指向const的指针 const void* p;
指向const的const指针 const void* const p;
Top
回复人:cdo(原来我什么都不会) ( 一级(初级)) 信誉:100 2005-7-3 23:03:22 得分:0
?


9、如何交换两个变量,不能用中间变量。


a=a+b;
b=a-b;
a=a-b;


----------------------------------------


这样的解答对吗?不够一般化呀。
Top
回复人:junnyfeng(风歌) ( 一星(中级)) 信誉:107 2005-7-4 0:26:30 得分:0
?


10、c与c++ static函数的区别???


作用域不同
Top
回复人:kokcc() ( 一级(初级)) 信誉:100 2005-7-4 1:31:47 得分:0
?


交换变量不用临时变量可以用位运算^
例:
a^=b;
b^=a;
a^=b;
即可
Top
回复人:jyk(喜欢编程。和气生财。共同提高。共同进步) ( 一级(初级)) 信誉:100 2005-7-4 6:16:15 得分:0
?


9、如何交换两个变量,不能用中间变量。


a=a+b;
b=a-b;
a=a-b;


按指针运算就行,具体的忘记怎么写了。
Top
回复人:lwsnake(学习) ( 一级(初级)) 信誉:100 2005-7-4 7:56:13 得分:0
?


UP
Top
回复人:clear117(小风) ( 一级(初级)) 信誉:100 2005-7-4 8:38:04 得分:0
?


mark
Top
回复人:sea2000cn(我想我是海) ( 二级(初级)) 信誉:100 2005-7-4 8:42:58 得分:0
?


kokcc()的方法是可行的
Top
回复人:pipilupzj(皮皮鲁) ( 一级(初级)) 信誉:100 2005-7-4 9:47:17 得分:0
?


mark先
Top
回复人:firstdreamer(我不懂指针和OOP) ( 二级(初级)) 信誉:100 2005-7-4 9:58:39 得分:0
?


mark......
Top
回复人:ywyw(遥望) ( 一级(初级)) 信誉:100 2005-7-4 10:13:34 得分:0
?


好可怕的面试题
Top
回复人:kobelin1980() ( 一级(初级)) 信誉:100 2005-7-4 10:34:51 得分:0
?


这个公司是不是只招一人啊
Top
回复人:Maconel(Maconel) ( 二级(初级)) 信誉:100 2005-7-4 10:42:38 得分:0
?


/************************************
函数作用:
不用第三个变量,交换2个变量。
不但支持普通基本变量类型,还支持类变量。
参数:
T& t1
第一个变量
T& t2
第二个变量
返回值:
void
备注:
作者及时间:
Maconel
2005-07-04上午
************************************/
template <class T>
void swap(T& t1, T& t2)
{
BYTE* byp1 = (BYTE*)&t1;
BYTE* byp2 = (BYTE*)&t2;


for (int i=0; i<sizeof(T); i++)
{
byp1[i] ^= byp2[i];
byp2[i] ^= byp1[i];
byp1[i] ^= byp2[i];
}
}


这样的函数可以交换2个类的对象。
简单测试了几种类都没有问题。
Top
回复人:bares() ( 一级(初级)) 信誉:94 2005-7-4 20:43:09 得分:0
?


mark
Top
回复人:richen_99(过去的就让它过去吧~~~) ( 一级(初级)) 信誉:100 2005-7-4 21:13:26 得分:0
?


a ^= b ^= a ^= b;


Top
回复人:yxz149(叶新州) ( 一级(初级)) 信誉:100 2005-7-4 21:28:31 得分:0
?


觉得跟c++的那些问题都不是很难,
其他俺目前就不大清楚了。。。
Top
回复人:qiasa() ( 一级(初级)) 信誉:100 2005-7-4 22:00:03 得分:0
?


就答出来了3道
Top
回复人:lineuser(蓝冰) ( 一级(初级)) 信誉:100 2005-7-4 22:33:32 得分:0
?


mark


Top
回复人:begincsdn(CNetware) ( 五级(中级)) 信誉:100 2005-7-5 9:21:29 得分:0
?


他们要的是一个熟悉系统底层的人。
特别是熟悉各种语言机制的人。
这种人可遇不可求啊。
Top
回复人:Cnwanglin(林) ( 一级(初级)) 信誉:100 2005-7-5 10:40:51 得分:0
?


。。。 辛苦阿
Top
回复人:myview(大白菜) ( 一级(初级)) 信誉:100 2005-7-5 12:04:53 得分:0
?


干脆找个机器人算了
Top
回复人:lanphaday(恋花蝶) ( 一级(初级)) 信誉:100 2005-7-5 13:22:59 得分:0
?


小兵只能是小兵.带着自己的情绪去学习或者选择学习的内容,永远成不了将军.要知道,将军往往都是向敌军的将军学习的.
Top
回复人:PennySZ() ( 一级(初级)) 信誉:100 2005-7-5 15:08:12 得分:0
?


9、如何交换两个变量,不能用中间变量。


a=a+b;
b=a-b;
a=a-b;


按指针运算就行,具体的忘记怎么写了。
=========================================
这个解答是错误的,并没有考虑到溢出的问题。
Top
回复人:hollandjzy(小羊) ( 一级(初级)) 信誉:100 2005-7-5 15:22:53 得分:0
?


哎 不会 毕业后怎么办
Top
回复人:CounterHack(反击黑客) ( 一级(初级)) 信誉:100 2005-7-5 15:31:53 得分:0
?


9、如何交换两个变量,不能用中间变量。


a=a+b;
b=a-b;
a=a-b;


按指针运算就行,具体的忘记怎么写了。
=========================================
这个解答是错误的,并没有考虑到溢出的问题。
--------------------------------------------------------
溢出不会导致结果错误!(当然,abc类型要一致)
Top
回复人:broodpool() ( 一级(初级)) 信誉:100 2005-7-5 16:13:30 得分:0
?


9、如何交换两个变量,不能用中间变量。
x = x * y;
y = x / y;
x = x / y;


大家看看,这个能不能得到答案。
Top
回复人:july81(鸟) ( 一级(初级)) 信誉:100 2005-7-5 16:19:01 得分:0
?


楼上的我说你要碰运气才可以。
Top
回复人:liun02(流年) ( 二级(初级)) 信誉:100 2005-7-5 16:57:13 得分:0
?


这么招人能招到吗?
Top
回复人:LordSimon(LordSimon) ( 一级(初级)) 信誉:100 2005-7-5 17:47:40 得分:0
?


5、二叉排序树和哈希表那个查找效率高,实用于pda 。
除了这个...其它都不知道
Top
回复人:wjlsmail(小脖领) ( 一级(初级)) 信誉:100 2005-7-5 17:54:38 得分:0
?


Mark
Top
回复人:seandsky(路人甲) ( 一级(初级)) 信誉:100 2005-7-5 17:58:36 得分:0
?


小兵只能是小兵.带着自己的情绪去学习或者选择学习的内容,永远成不了将军.要知道,将军往往都是向敌军的将军学习的.
-----------------------------------------------------------


稍微有点道理,但是逆反自己的情绪去选择学习的内容,你就可以做将军?
Top
回复人:wiali(维埃里) ( 一级(初级)) 信誉:99 2005-7-5 20:23:43 得分:0
?


小兵只能是小兵.带着自己的情绪去学习或者选择学习的内容,永远成不了将军.要知道,将军往往都是向敌军的将军学习的.
-----------------------------------------------------------
完全不同意,就是要选择的学,学错方向了,说明你的判断能力有问题,方向对了,只要精通一样就可以了,其它都应该可以触类旁通,如果你还是做不到,看什么都新鲜,需要靠知识面来壮壮门面,那说明你本身就没有做将军的素质,那就该认了自己不是做将军的料。


另外,向敌军学习也是有选择的学的!
Top
回复人:GeminiXXXCC(吕布) ( 二级(初级)) 信誉:99 2005-7-5 22:10:49 得分:0
?


const void *p 和void const *p是一个意思。
const void *p ;
void const *p ;
void* const p ;
=.=
Top
回复人:yhbttfile(小兵) ( 二级(初级)) 信誉:100 2005-7-5 22:48:18 得分:0
?


呵呵,人家是在问问题,怎么聊起怎么学习了呢?


说实在的,我在很多场合都避免深入谈.net、java,不是我没有去了解过,是我的确对他们有自己的某种偏见,就像大家所具有的偏见一样。其实我更愿意谈ice、ace等。
.net的很多设计思路其实都是来源于C++,JAVA也是。JAVA更多设计思路是来源于smalltalk(语法风格更像C++)。
JAVA 和.NET中很多语言特点还是非常优秀的。如JAVA的forName,根据名称就可以实例化对象,C++就不可能实现(因为C++是静态语言)。. NET的委托,用起来很直观,C++的委托要自己实现;还有.NET支持DLL分版本发布;还有.NET支持线程,这些C++目前都没有。


C+ +也有自己的优势,它是一个开放的协议,所有公司都可以发展它。它不会让你随便跨入一个利益集团。你不喜欢VC,你可以用GCC,也可以选择DEV_C+ +/C++B等。没有人限制你,这个工具写的代码很容易移植到其他平台。另,不得不提一下C++的模板,这个功能使程序员得以实现泛型设计思想(目前,据说JAVA正在考虑增加模板功能)。另,使用和研究C++的程序员集团军比任何一个语言都多。


希望大家不要讨论该学什么。自己多看就有选择了。
难道谁都希望成为将军吗?“不想当元帅的士兵就不是好兵”被我们用得太多了。


的确如wiali(维埃里)所说,其实只要精通一样就好了。程序员太辛苦了,大家应该拿更多的时间去锻炼和散步。多注意自己的身体,身体才是革命他妈。GOOD LUCK TO ALL!
Top
回复人:xiaolizi(小李子) ( 三级(初级)) 信誉:100 2005-7-6 0:03:07 得分:0
?


小兵同志说得有点道理,鼓掌~~^_^
Top
回复人:gogdo(草草) ( 一级(初级)) 信誉:101 2005-7-6 5:35:28 得分:0
?


up


Top
回复人:clear117(小风) ( 一级(初级)) 信誉:100 2005-7-6 8:39:45 得分:0
?


说得好!! 小兵 支持~~~~~~
去TM的全面发展,那样除了后天努力,更重要的是有先天的条件。精通一样,胜过模模糊糊的十样。


对于学习方法,学习精神,每个人有不同的个性,不同的EQ,不同的目标(说的老成点就是人生观、世界观)
同一种方法并不适用所有人。逆反思维只对性格倔犟的人有用;有确定人生目标的要的是激励,“逆反”是种打击;性格柔弱的要的是鼓励,“逆反”是种摧残。


“程序员太辛苦了,大家应该拿更多的时间去锻炼和散步。多注意自己的身体,身体才是革命他妈。”真是经典,一语道破了程序员生活的真谛




Top
回复人:brianlu(-) ( 三级(初级)) 信誉:100 2005-7-6 9:52:48 得分:0
?


up
Top
回复人:nlstone(天外流星) ( 二级(初级)) 信誉:100 2005-7-6 10:53:37 得分:0
?


1、智能指针,com实现的原理,
智能指针就是用一个类来模拟指针的动作,并会自动销毁自己,包括一些引用计数,控制权转移之类的。com就是满足接口编程的二进制兼容协仪。
2、printf()可变参数如何实现
不懂
3、标准模板库vector追加数据如何实现。是底层如何实现,不能用现有的东东。
前面已经有人说过了
4、还有,java的垃圾收集机制如何实现为什么?如果是你自己实现垃圾收集机制,如何实
现? 用什么数据结构。
.net的看过一些,java的不知道
5、二叉排序树和哈希表那个查找效率高,实用于pda 。
哈希表查找的效率是无敌的,至于在pda上会不会因为内存的限制而有所不同,难说。
6、.net的底层实现机制。
就是一个虚拟机,调用系统API来生活。
7、进程间通信如何实现。
在windows中最多的是使用一些核心对象,信号量/文件映射等,泛而言之还有管道/消息之流
8、还有迭代问题,什么问题用迭代,迭代在操作系统中如何实现的 。
递归的问题用迭代,使用堆栈实现
9、如何交换两个变量,不能用中间变量。
老题目,不说了
10、c与c++ static函数的区别???
c里面是用来限制作用域(是吧?),C++里是用来放大作用域使其成为全局的
11、const 函数的作用,如何实现钩子函数。
不影响类的其它成员变量,借助函数指针实现钩子函数
12、两层容错技术怎么实现?
不懂
13、写出函数指针,函数返回指针,const指针,指向const的指针,指向const的const指针

easy, 就不写了
14、函数调用如何实现,注意什么问题。
不就是call吗? 注意传入前现场保护
15、指针和引用的差别,
引用是类型安全的,指针不是.(引用和指针本质是一样的,都是地址,只是引用多了类型检查而已)
16、拷贝构造函数如何实现,什么情况下会用到。
传一个本类的对象给构造函数。
很多情况,典型的是有深层拷贝的情况。
Top
回复人:jalang(冻天) ( 一级(初级)) 信誉:100 2005-7-6 11:28:43 得分:0
?


一个都不会..算了...我先去把厕所扫完再回来...mark....
Top
回复人:ensoniq() ( 一级(初级)) 信誉:100 2005-7-6 11:51:27 得分:0
?


这个是什么公司?
Top
回复人:ksksks(海洋) ( 一级(初级)) 信誉:100 2005-7-6 12:19:09 得分:0
?


9、如何交换两个变量,不能用中间变量。


a=a+b;
b=a-b;
a=a-b;


按指针运算就行,具体的忘记怎么写了。
=========================================
这个解答是错误的,并没有考虑到溢出的问题。
--------------------------------------------------------
溢出不会导致结果错误!(当然,abc类型要一致)
_________________________________________________________
用整形试了一下,果然不会出错,
那这个方法和 用异或 运算比较,
大家觉得算是个好方法吗?
起码速度没有 异或 快吧?/
Top
回复人:fallening() ( 一级(初级)) 信誉:100 2005-7-6 12:23:47 得分:0
?


旁边tk一下,顺便学习学习
Top
回复人:xinde() ( 一级(初级)) 信誉:100 2005-7-6 12:40:42 得分:0
?


现在找工作都要考试,晕
Top
回复人:youhaodeyi(友好的翼) ( 一级(初级)) 信誉:100 2005-7-6 13:15:25 得分:0
?


请问搂主:这是什么公司
Top
回复人:whatsouta(某疯子) ( 二级(初级)) 信誉:100 2005-7-6 19:42:56 得分:0
?


太多东西不知道的了。


楼主应该先不回答问题,先问他“你给多少钱??”。如果大于百万你再全部回答。
Top
回复人:only_C(幽幽) ( 一级(初级)) 信誉:100 2005-7-7 0:02:49 得分:0
?


但愿不要问我这些问题
Top
回复人:bilycc(晓雨) ( 一级(初级)) 信誉:100 2005-7-7 6:18:38 得分:0
?


妈哟。。要全能的啊?干。现在的公司真是什么都有。给的钱少不说要求还高。


xinde()


现在找工作都要考试,晕
考试当然多多少少都会有。






Top
回复人:mccxj(老鼠学习xmling。。。。。) ( 四级(中级)) 信誉:100 2005-7-7 8:33:24 得分:0
?


有难度呀。。学习。。


-----------------------------
http://web.likesp.com/mccxj/
个人主页,近期增加考试专题。。
个人目标:每天增加10条新的。。还可以把。。
决定把分类弄得更加详细。。如果有什么意见。。就提出来把。。谢谢。
-----------------------------


Top
回复人:sea2000cn(我想我是海) ( 二级(初级)) 信誉:100 2005-7-7 8:34:53 得分:0
?


居然只是实习生的笔试题,汗啊……
Top
回复人:liyuan02(梨园) ( 一级(初级)) 信誉:100 2005-7-7 19:19:40 得分:0
?


学习。。。。。。
Top
回复人:abeni(Abeni) ( 一级(初级)) 信誉:100 2005-7-7 20:35:46 得分:0
?


刚准备出去找工作,仅有的一点信心被你打没了!
[img]http://www.csdn.net/images/homeimage/csdn.gif[/img]
Top
回复人:K() ( 二级(初级)) 信誉:100 2005-7-8 0:02:42 得分:0
?


学习!
Top
回复人:lovesnow1314(流浪) ( 一级(初级)) 信誉:100 2005-7-8 0:45:12 得分:0
?


mark


Top
回复人:zsx123(zhongshexiang@126.com) ( 一级(初级)) 信誉:100 2005-7-9 14:43:56 得分:0
?


学习
Top
回复人:humanity(总是偷窥 Java & XML) ( 一级(初级)) 信誉:100 2005-7-9 15:24:25 得分:0
?


有简单的也有难的。一张纸就搞定了。


北大青鸟出来的估计搞定所有的也不见得录取 ?


前提是要你确实思考过几年问题。
Top
回复人:chenminyi(mike狼) ( 一级(初级)) 信誉:100 2005-7-9 21:13:06 得分:0
?


我发觉上述问题有80%以上的问题都在《C++程序设计语言》上有一定的描述和应用,所以好高兴(本人正在用此书),不过正向译者所说的:“了解本书的一般性内容需要花一定的时间,而融会贯通则更需要很大的努力。”内容太丰富了可惜自己小部分还不理解大部分还不会应用。
还有对于上述两数交换不用临时变量的问题,好象几种方法都有某些数不适用,“+,*”实现的比较找出不适用的范例,而“^”的不适用情况以前好象在《深入理解计算机系统》上看过,上次去找没找出来,能否那位让我温顾一下?我觉得垃圾收集机制是上述问题中最难的(.NET我不了解)
Top
回复人:ryan_1223(乌鸦) ( 二级(初级)) 信誉:100 2005-7-9 21:18:14 得分:0
?


mark~!
Top
回复人:manuever() ( 一级(初级)) 信誉:100 2005-7-9 21:33:58 得分:0
?


不错
学习
Top
回复人:ExtUSA(身体好,才是真好!) ( 一级(初级)) 信誉:100 2005-7-9 23:14:46 得分:0
?


这题目也就是专门吓唬学生滴...
Top
回复人:aizyhan(Aizy) ( 一级(初级)) 信誉:100 2005-7-10 11:34:23 得分:0
?


好变态啊~~毕业后怎么办啊~~没前途了…………
Top
回复人:wufangding2001(孤独一生) ( 一级(初级)) 信誉:100 2005-7-10 12:16:56 得分:0
?


只看地懂一个~~
Top
回复人:boyplayee(深度解析编程) ( 一级(初级)) 信誉:96 2005-7-10 13:41:17 得分:0
?


mark
Top
回复人:xiaojun789(笑) ( 一级(初级)) 信誉:100 2005-7-11 12:56:28 得分:0
?


up
Top
回复人:khalidwind(追风浪子) ( 一级(初级)) 信誉:99 2005-07-12 23:10:00 得分:0
?
1、智能指针,
看样子像指针的东西。一般是这样的形式
template<class T>
com实现的原理,
2、printf()可变参数如何实现
3、标准模板库vector追加数据如何实现。是底层如何实现,不能用现有的东东。
4、还有,java的垃圾收集机制如何实现为什么?如果是你自己实现垃圾收集机制,如何实
现? 用什么数据结构。
5、二叉排序树和哈希表那个查找效率高,实用于pda 。
6、.net的底层实现机制。
7、进程间通信如何实现。
8、还有迭代问题,什么问题用迭代,迭代在操作系统中如何实现的 。
9、如何交换两个变量,不能用中间变量。
10、c与c++ static函数的区别???
11、const 函数的作用,如何实现钩子函数。
12、两层容错技术怎么实现?
13、写出函数指针,函数返回指针,const指针,指向const的指针,指向const的const指针

14、函数调用如何实现,注意什么问题。
15、指针和引用的差别,
16、拷贝构造函数如何实现,什么情况下会用到。
Top
回复人:khalidwind(追风浪子) ( 一级(初级)) 信誉:99 2005-07-12 23:23:00 得分:0
?
重写,刚才搞错了
1、智能指针,
样子像指针,一般是这样的东西。
template<class T>
class smpoint
{public:
smpoint(T* p):m_p(o){}
operator *(){return *p;}
operator->(){return p;}
}
最常见的智能指针是auto_ptr


不懂com实现的原理,
2、printf()可变参数如何实现 ,题目没看懂
3、标准模板库vector追加数据如何实现。是底层如何实现,不能用现有的东东。
stl的东西说起来很麻烦的。但其实就是要重新分配空间,而且是原空间的两倍,然后复制原来的数据到新的空间,再释放原来的空间。至于分配,STL采用两级分配,也可以自己传入allocate,很多很多东西的.


4、还有,java的垃圾收集机制如何实现为什么?如果是你自己实现垃圾收集机制,如何实
现? 用什么数据结构。
我不懂,我想如果是我的话用堆栈啊。堆栈本来就是自动释放空间的嘛,对吗


5、二叉排序树和哈希表那个查找效率高,实用于pda 。
啥叫二叉排序树?是AVL,RBTree?不懂,
6、.net的底层实现机制。
不懂
7、进程间通信如何实现。
IPC:shared memory,pipe,socket,semaphore,message。
8、还有迭代问题,什么问题用迭代,迭代在操作系统中如何实现的 。
当不希望客户访问到内部数据,或者遍历功能较麻烦需要封装而又希望提供遍历功能的时候就要用迭代。操作系统有迭代?我没听说过。
9、如何交换两个变量,不能用中间变量。
网上有,但要我自己做我不会
10、c与c++ static函数的区别???
有同样的地方,比如函数中的static. 而C中全局static表示仅仅对单元内可见,C++类中的static在程序刚开始时分配内存,所有对象维护同一份static变量。
11、const 函数的作用,如何实现钩子函数。
const函数?就是使非const对象不能调用,以次来保护内部数据成员。
12、两层容错技术怎么实现?
不懂
13、写出函数指针,函数返回指针,const指针,指向const的指针,指向const的const指针

void (*f)()
void* f()
const int*
int* const
const int* const
14、函数调用如何实现,注意什么问题。
ebp入栈,参数入栈,返回地址入栈,esp扩展,局部变量入栈。
15、指针和引用的差别,
引用必须初始化,引用不能改变
16、拷贝构造函数如何实现,什么情况下会用到。
class A
{
public:
A(const A& obj){}
}
A a;
A b(a);
A b = a;
A f(A a){},传参和返回都会调用copy construct
Top
回复人:wsnly13(大刀王五) ( 一级(初级)) 信誉:100 2005-07-13 16:40:00 得分:0
?
多注意自己的身体,身体才是革命他妈


赞一个!!
Top
回复人:AntonlioX(做人要厚道) ( 一级(初级)) 信誉:100 2005-07-13 21:50:00 得分:0
?
不是面试题 更象是学校里的考试题
Top
回复人:cyblueboy83(爱情白痴—电脑迷) ( 一级(初级)) 信誉:100 2005-07-13 23:37:00 得分:0
?

很多不懂
Top
回复人:liuhaimiao() ( 一级(初级)) 信誉:100 2005-07-14 12:44:00 得分:0
?
好难啊,看了让人汗颜
Top
回复人:liuhaimiao() ( 一级(初级)) 信誉:100 2005-07-14 13:11:00 得分:0
?
我最怕考试了,一考试就发现自己会的好少
Top
回复人:xyking361(林梦怡) ( 一级(初级)) 信誉:100 2005-07-14 17:21:00 得分:0
?
最近练习了易筋经。发现编程能力进步了不少,人也变得更漂亮了,脑子也更聪明了,每次考试都考一百分。
Top
回复人:boyplayee(深度解析编程) ( 一级(初级)) 信誉:96 2005-07-16 19:19:00 得分:0
?

Top
回复人:runfeng(sunday) ( 一级(初级)) 信誉:100 2005-07-17 06:50:00 得分:0
?
up
Top
回复人:zhk_1030(I LOVE C++) ( 一级(初级)) 信誉:100 2005-07-17 10:38:00 得分:0
?
这家单位是不是想招能跑全场的计算机教师呀!
Top
回复人:zerocold(江城浪子) ( 一级(初级)) 信誉:100 2005-07-17 13:18:00 得分:0
?
9、如何交换两个变量,不能用中间变量。
用异或,假设@表示异或
因为A@A == 0,0@A == A并且异或运算满足交换律和结合律
所以用下面过程可以交换A,B
1)A = A@B
2)B = A@B //此时B中为原始的A 也就是说A@B@B == A@0 ==A
3)A = A@B //此时A中为原始的B 也就是说(A@B)@(A@B@B) == (A@B@A) == (A@A)@B == B
Top
回复人:hbj24(那A安捏) ( 一级(初级)) 信誉:100 2005-07-17 13:22:00 得分:0
?
这。。也太。。我只能顶了
Top
回复人:zerocold(江城浪子) ( 一级(初级)) 信誉:100 2005-07-17 13:25:00 得分:0
?
10、c与c++ static函数的区别???
c语言中用static 修饰的函数表示该函数的名字只有局部的作用域
c++的全局函数用static 修饰和一样的意思。此时建议用无名名字空间包含该函数而不是static,以免和c++类成员函数混淆,因为C++类的成员函数如果用static修饰表示是类的作用域而不是对象作用域,应该用类名来引用而不是对象名。
Top
回复人:zerocold(江城浪子) ( 一级(初级)) 信誉:100 2005-07-17 13:34:00 得分:0
?
printf的实现可以看看linux内核,
当初linus可能也是怕麻烦,请他一个朋友写了一个vsprintf,vsprintf的以va_list为参数,中间用了一大堆的if来判断%x%d%s之类,这个没什么奥妙,其实关键部分是可变参数表,这个估计要参考c语言的实现了
Top
回复人:zerocold(江城浪子) ( 一级(初级)) 信誉:100 2005-07-17 13:41:00 得分:0
?
拷贝构造函数一般在用一个对象初始化一个变量的时候用,实现时要主要当类中有指针变量成员时,不能简单拷贝指针变量的值,而要为指针分配内存,在拷贝指针所指内存的内容。
Top
回复人:zc8834100(斗牛) ( 一级(初级)) 信誉:100 2005-07-17 13:53:00 得分:0
?
好 恐怖 的面试题目!
Top
回复人:CoreWar() ( 一级(初级)) 信誉:100 2005-07-17 14:12:00 得分:0
?
题目出的挺有水平的。
Top
回复人:hewittlee(只爱C++) ( 二级(初级)) 信誉:100 2005-07-17 15:51:00 得分:0
?
up
Top
回复人:chenminyi(mike狼) ( 一级(初级)) 信誉:100 2005-07-24 20:31:00 得分:0
?
可变参数表再哪能找到??
<<C程序设计语言>>里面也没有说怎么实现的
Top
回复人:HermeX() ( 一级(初级)) 信誉:100 2005-07-24 20:39:00 得分:0
?
这是moto的面试题
Top
回复人:mostideal(三甲) ( 四级(中级)) 信誉:100 2005-07-24 20:50:00 得分:0
?
ding
Top
回复人:Jim_King_2000() ( 二级(初级)) 信誉:100 2005-07-24 21:15:00 得分:0
?
神仙去参加这样的面试都会被搞死!广大程序员们,我们应该把主要精力放在设计上。技术只要通一样就够了。否则再给一辈子也学不完。当然,身体和妞也都是我们不可缺少的……
Top
回复人:wengsea() ( 一级(初级)) 信誉:100 2005-07-24 22:07:00 得分:0
?
10.c里 static 函数是内部函数,作用于本文件
Top
回复人:WingForce(初六,履霜,坚冰至。) ( 四级(中级)) 信誉:99 2005-07-24 22:08:00 得分:0
?
交换2个任意类型的变量,不使用中间变量是不可能的
Top
回复人:HermeX() ( 一级(初级)) 信誉:100 2005-07-24 22:22:00 得分:0
?
楼上的,不使用中间变量交换任意类型的两个变量是可以实现的。
请参见前面 zerocold(江城浪子) ,kokcc() 等人的大作
Top
回复人:HermeX() ( 一级(初级)) 信誉:100 2005-07-24 22:24:00 得分:0
?
其实moto的考官并不要求每个问题都能答上,有些问题是有关联的,哪怕你只能答对几个,但答得很好,考官就可以从中看出你在某一方面特别强。他就会考虑录取。相反每个问题都能答上一点却讲不清楚的反而不会被录取。
Top
回复人:zcainiao(瘦不了) ( 一级(初级)) 信誉:100 2005-07-25 08:23:00 得分:0
?
第9个问题:
x=a;//a是常量
y=b;//b是常量
x=x+y;//x=a+b
y=x-y;//y=x-b=(a+b)-b=a
x=x-y;//x=x-y=(a+b)-a=b
写完之后才发现前面有人回答了,唉,贴上去吧
Top
回复人:lw1a2(一刀) ( 五级(中级)) 信誉:101 2005-07-25 08:38:00 得分:0
?
up
Top
回复人:henan_lujun(地平风线) ( 一级(初级)) 信誉:100 2005-07-25 08:40:00 得分:0
?
MOTO要这么厉害的人么!十项全能!
Top
回复人:wave2050(hello word) ( 二级(初级)) 信誉:100 2005-07-25 08:41:00 得分:0
?
好象看过呀!
Top
回复人:yc0188(守护瓶(萍)) ( 三级(初级)) 信誉:100 2005-07-25 08:50:00 得分:0
?
干脆不干了.
Top
回复人:sdbtb(sdbtb) ( 二级(初级)) 信誉:100 2005-07-28 14:23:00 得分:0
?
还不结贴,都沉到底了。
我来解释一下这个面试题目的来历吧:
最初是电子科技大学的一位研究生gg到成都Moto应聘实习生之后回到学校的BBS上发的这个
贴子(成都Moto实习生和正式员工的面试是一起进行的,所以难度相当)。这些题目都是
面试题,而非笔试,笔试实际上容易得多(我做笔试题感觉不难,除了软件工程的一些东西
,因为那些知识我看得很少)。面试其实也没那么难,比如问你.NET的底层实现机制,我想
可能是这位兄弟说他会.NET,人家才问他这个问题。我参加面试的时候面试官只捡我简历上
涉及的知识提问,其实也不难,只要自己的确如自己简历上所说,我的笔试和面试都是轻松
加愉快。
Top
回复人:jcqstc(jcqstc) ( 一级(初级)) 信誉:100 2005-07-28 14:33:00 得分:0
?
这个帖子大概被楼主忘记了吧,都快有1个月了,结了吧
Top
回复人:guycs(年轻人) ( 一级(初级)) 信誉:100 2005-07-28 15:47:00 得分:0
?
云~~ 佩服 覆盖面不小~~
Top
回复人:jinder22(jinder22) ( 一级(初级)) 信誉:100 2005-07-28 16:17:00 得分:0
?
1指针与引用的区别
在任何情况下都不能使用指向空值的引用。一个引用必须总是指向某些对象。因此如果你使用一个变量并让它指向一个对象,但是该变量在某些时候也可能不指向任何对象,这时你应该把变量声明为指针,因为这样你可以赋空值给该变量。相反,如果变量肯定指向一个对象,例如你的设计不允许变量为空,这时你就可以把变量声明为引用。
不存在指向空值的引用这个事实意味着使用引用的代码效率比使用指针的要高。因为在使用引用之前不需要测试它的合法性。相反,指针则应该总是被测试,防止其为空。
指针与引用的另一个重要的不同是指针可以被重新赋值以指向另一个不同的对象。但是引用则总是指向在初始化时被指定的对象,以后不能改变,但是指定的对象其内容可以改变。


总的来说,在以下情况下你应该使用指针,一是你考虑到存在不指向任何对象的可能(在这种情况下,你能够设置指针为空),二是你需要能够在不同的时刻指向不同的对象(在这种情况下,你能改变指针的指向)。如果总是指向一个对象并且一旦指向一个对象后就不会改变指向,那么你应该使用引用。
Top
回复人:ljp_0913(霹雳贝贝) ( 一级(初级)) 信誉:100 2005-07-28 17:57:00 得分:0
?
const指针:const void *ptr或者是void const *ptr
指向const的指针: void *const ptr1;或者是*const void ptr1;
指向const的 const指针:const void *const ptr2或者是void const *const ptr2;
函数指针:void (*ptr)();
返回函数的指针 void *function();
Top


20.


主  题: 大家好,有一道C语言面试题目请教各位!
作  者: NEThengxin (IT_菜鸟)
等  级:
信 誉 值: 100
所属论坛: C/C++ C语言
问题点数: 20
回复次数: 7
发表时间: 2005-07-27 08:58:28


随机搜索1到1000之间的一个数字,用最简单的方法来实现!
回复人:zhouhuahai(大草原) ( 二级(初级)) 信誉:100 2005-07-27 09:31:00 得分:0
?
int value;
srand(time(NULL));
value = rand() % 1000 + 1;
Top
回复人:corrupt(学习数学中...........) ( 一级(初级)) 信誉:100 2005-07-27 09:46:00 得分:0
?
最快当然是 用二分法了~~
Top
回复人:xuanwenchao(xuanwenchao) ( 二级(初级)) 信誉:100 2005-07-27 09:54:00 得分:0
?
二分法
Top
回复人:wxiaolanzhuw(w小懒猪w) ( 一级(初级)) 信誉:100 2005-07-27 10:14:00 得分:0
?
问的是产生随机数的方法吧?
大草原的对,即使是做查找二分法也不见得是最好的
Top
回复人:windking21(暗淡) ( 一级(初级)) 信誉:100 2005-07-27 10:18:00 得分:0
?
srand(unsigned int (time(0)) );


while(val == 0)
{
val = rand()%10;
}
for(int i = 0;i<2;i++ )
{
val = (rand() % 10) + val*10;
}
fout<<val<<endl;
}
Top
回复人:redspider9999(亢龙有悔) ( 一级(初级)) 信誉:100 2005-07-27 10:41:00 得分:0
?
zhouhuahai(大草原) 的是正解
基本上生成任意范围的随机数都是这个模式
Top
回复人:mefit(何足道) ( 三级(初级)) 信誉:100 2005-07-27 18:28:00 得分:0
?
牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛xxxxxxxx牛牛牛牛牛
牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛xxxxxxxxxxxxxxxxxx牛牛牛牛
牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx牛牛牛牛
牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx牛牛牛牛牛牛
牛牛牛牛牛牛牛牛牛牛牛xxxxxxxx牛xxxxxxxxxxxxxxxxxxxxxx牛牛牛牛牛半牛牛牛牛
牛牛牛牛牛牛牛牛xxxxxxxxxxxxxx牛xxxxxx牛牛xxxxxxxxxx牛牛牛牛牛牛牛牛牛牛牛
牛牛牛xxxxxxxxxxxxxxxxxxxxxxxx牛牛牛牛牛牛xxxxxxxx牛牛牛牛牛牛牛牛牛牛牛牛
牛xxxxxxxxxxxxxxxxxxxxxxxxxxxx牛牛牛牛牛牛xxxxxxxx牛牛牛牛牛牛牛牛牛牛牛牛
牛xxxxxxxxxxxxxxxxxxxxxxxx牛牛牛牛牛牛牛xxxxxxxxxxxxxxxxxxxxxx牛牛牛牛牛牛
牛xxxxxxxxxxxxxxxxxxxxxxxx牛牛牛牛牛牛xxxxxxxxxxxxxxxxxxxxxxxxxxxx牛牛牛牛
牛牛xxxxxxxxxxxxxxxxxxxx牛牛牛牛牛xxxxxxxxxxxx牛牛牛xxxxxxxxxxxxxx牛牛牛牛
牛牛牛牛牛牛牛牛xxxxxxxx牛牛牛牛牛xxxxxxxx牛牛牛牛牛牛xxxxxxxxxx牛牛牛牛牛
牛牛牛牛牛牛牛牛xxxxxxxx牛牛牛牛xxxxxxxx牛牛xxxx牛牛牛xxxxxxxxxx牛牛牛牛牛
牛牛牛牛牛牛牛牛xxxxxxxx牛牛牛牛xxxxxxxx牛牛xxxxxxxx牛xxxxxxxxxx牛牛牛牛牛
牛牛牛牛牛牛牛牛xxxxxxxx牛牛牛牛xxxxxxxx牛牛xxxxxxxx牛xxxxxxxxxx牛牛牛牛牛
牛牛牛牛牛牛牛牛xxxxxxxx牛牛牛牛xxxxxxxx牛牛xxxxxx牛牛xxxxxxxxxx牛牛牛牛牛
牛牛牛牛牛牛牛牛xxxxxxxx牛牛牛牛xxxxxxxx牛牛xxxxxx牛牛xxxxxxxxxx牛牛牛牛牛
牛牛牛牛牛牛牛牛xxxxxxxx牛牛牛牛xxxxxxxx牛xxxxxxxx牛牛xxxxxxxxxx牛牛牛牛牛
牛牛牛牛牛牛牛牛xxxxxxxx牛牛牛牛xxxxxxxx牛xxxxxxxx牛牛xxxxxxxxxx牛牛牛牛牛
牛牛牛牛牛牛牛牛xxxxxxxx牛牛牛牛xxxxxxxx牛xxxxxxxx牛牛xxxxxxxxxx牛牛牛牛牛
牛牛牛牛牛牛牛牛xxxxxxxx牛牛牛牛xxxxxxxx牛xxxxxxxx牛牛xxxxxxxxxx牛牛牛牛牛
牛牛牛牛牛牛牛牛xxxxxxxx牛牛牛牛xxxxxx牛牛xxxxxxxx牛牛xxxxxxxxxx牛牛牛牛牛
牛牛xxxx牛牛牛xxxxxxxxxx牛牛牛牛xxxxxx牛牛xxxxxx牛牛牛xxxxxxxxxx牛牛牛牛牛
牛牛xxxxxxxxxxxxxxxxxxxx牛牛牛牛牛xxxx牛牛xxxx牛牛牛牛xxxxxxxxxx牛牛牛牛牛
牛牛牛xxxxxxxxxxxxxxxxxx牛牛牛牛牛牛牛牛xxxxxx牛牛牛牛xxxxxxxx牛牛牛牛牛牛
牛牛牛牛牛xxxxxxxxxxxxxx牛牛牛牛牛牛牛牛xxxxxx牛xxxxxxxx牛牛牛牛牛牛牛牛牛
牛牛牛牛牛牛xxxxxxxxxxxx牛牛牛牛牛牛牛xxxxxxxx牛牛xxxxxxxx牛牛牛牛牛牛牛牛
牛牛牛牛牛牛牛牛牛xxxxxx牛牛牛牛牛牛xxxxxxxxxx牛牛牛xxxxxxxxxxxxxx牛牛牛牛
牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛xxxxxxxxxxxx牛牛牛牛牛xxxxxxxxxxxx牛牛牛牛
牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛xxxxxxxxxxxx牛牛牛牛牛牛xxxxxxxxxxxxxx牛牛牛
牛牛牛牛牛牛牛牛牛牛牛牛牛牛xxxxxxxxxx牛牛牛牛牛牛牛牛牛xxxxxxxxxxxx牛牛牛
牛牛牛牛牛牛牛牛牛牛牛牛牛xxxxxxxxxx牛牛牛牛牛牛牛牛牛牛牛xxxxxxxx牛牛牛牛
牛牛牛牛牛牛牛牛牛牛牛牛xxxxxx牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛xxxxxx牛牛牛牛
牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛
Top


21.
主  题: 一道面试题目
作  者: CSam ()
等  级:
信 誉 值: 100
所属论坛: C/C++ C语言
问题点数: 20
回复次数: 59
发表时间: 2005-7-19 1:34:23




不用中间变量,交换两个变量的值.(用伪代码写出)
回复人:darkstar21cn(爱上小猫的小狗)(读不懂爱情所以来读程序) ( 五级(中级)) 信誉:99 2005-7-19 1:57:53 得分:0
?


a = a + b;
b = a - b;
a = a -b;
Top
回复人:lancycis(风雨交加) ( 一级(初级)) 信誉:100 2005-7-19 2:02:35 得分:0
?


括号里是注释
(设A=a,B=b)
a=a+b (a=A+B)
b=a+b (b=A+B+B)
a=b-a (a=(A+B+B)-(A+B)=B)
b=b-2*a (b=(A+B+B)-2*B=A)


这里AB2个变量只是用来解释,实际并没有用到,而且这段代码也不是最优
Top
回复人:lancycis(风雨交加) ( 一级(初级)) 信誉:100 2005-7-19 2:04:07 得分:0
?


晕,做沙发的是最优解
Top
回复人:foochow(恰似你的温柔) ( 一星(中级)) 信誉:100 2005-7-19 8:15:13 得分:0
?


a^=b^=a^=b
Top
回复人:conglingkaishi(从零开始) ( 二级(初级)) 信誉:100 2005-7-19 8:24:04 得分:0
?


楼上的,贼强!
Top
回复人:llf_hust() ( 五级(中级)) 信誉:100 2005-7-19 8:38:33 得分:0
?


void Swap(int *a,int *b)
{
*a = *a ^ *b;
*b = *a ^ *b;
*a = *a ^ *b;
}
Top
回复人:web_gus(penny 路漫漫其修远兮,吾将上下而求索) ( 一级(初级)) 信誉:100 2005-7-19 8:52:26 得分:0
?


又学了一招
Top
回复人:cheng_fu(扬风太阳雨) ( 一级(初级)) 信誉:100 2005-7-19 8:53:28 得分:0
?


这个题目有点那个啊,程序是写给人看的
Top
回复人:hchack(无) ( 一级(初级)) 信誉:100 2005-7-19 9:32:15 得分:0
?


a^=b^=a^=b
这是什么意思,我怎么不明白?
Top
回复人:lxhong1980(娶个善善良良的妻子,养个聪聪明明的孩子) ( 一级(初级)) 信誉:100 2005-7-19 9:34:27 得分:0
?


void swap(int &a, int &b)
{
if ( a>b )
{
for (int i=0; i<a-b; i++)
{
a--;
b++;
}
}
else
{
for (int i=0; i<b-a; i++)
{
a++;
b--;
}
}
}


Top
回复人:surfer2888() ( 一级(初级)) 信誉:100 2005-7-19 9:38:44 得分:0
?


n
Top
回复人:Roaming_Sheep(Roaming Sheep) ( 四级(中级)) 信誉:100 2005-7-19 9:57:32 得分:0
?


a^=b^=a^=b
这是什么意思,我怎么不明白?
————————————


就是:


a^=b;
b^=a;
a^=b;
Top
回复人:CSam() ( 一级(初级)) 信誉:100 2005-7-19 11:42:13 得分:0
?


括号里是注释
(设A=a,B=b)
a=a+b (a=A+B)
b=a+b (b=A+B+B)
a=b-a (a=(A+B+B)-(A+B)=B)
b=b-2*a (b=(A+B+B)-2*B=A)
这里AB2个变量只是用来解释,实际并没有用到,而且这段代码也不是最优


说实在的真是有些看不懂,太深奥了吧.
Top
回复人:kernelxu(残眉) ( 一级(初级)) 信誉:100 2005-7-19 12:04:26 得分:0
?


老掉牙的题了!
Top
回复人:xtao2003(中国制造) ( 一级(初级)) 信誉:100 2005-7-19 14:04:40 得分:0
?


都是牛人啊,学习!!!
Top
回复人:bossalex(ice) ( 一级(初级)) 信誉:100 2005-7-20 9:58:06 得分:0
?


1楼的答案就非常好了。后面越写越复杂。
Top
回复人:ply6669747(阿七) ( 一级(初级)) 信誉:100 2005-7-20 13:05:59 得分:0
?


收藏
thanks
Top
回复人:xufangrui(独孤风清) ( 一级(初级)) 信誉:100 2005-7-20 13:16:07 得分:0
?


牛人好多!
Top
回复人:apollon_hhy(一天五十页!) ( 一级(初级)) 信誉:100 2005-7-20 13:28:02 得分:0
?


llf_hust() 你的有问题吧
void Swap(int *a,int *b)
{
*a = *a ^ *b;
*b = *a ^ *b;
*a = *a ^ *b;
}
不信 你举个例子试试


Top
回复人:cky2() ( 二级(初级)) 信誉:99 2005-7-20 16:02:18 得分:0
?


根本就不可能有这种方法
Top
回复人:i33333(Microwish_grasstalent) ( 一级(初级)) 信誉:100 2005-7-20 16:14:43 得分:0
?


void swap(void *a, void *b)
{
*a+=*b;
*b=*a-*b;
*a=*a-*b;
return;
}
Top
回复人:willianzhong(我要Linux) ( 一级(初级)) 信誉:97 2005-7-20 16:54:30 得分:0
?


void swap(void *a, void *b)
{
*a+=*b;
*b=*a-*b;
*a=*a-*b;
return;






晕,你明明时学 第一楼得啊 抄袭
Top
回复人:klime(笨猪学看书) ( 一级(初级)) 信誉:100 2005-7-20 17:19:06 得分:0
?


一楼的英明!!!学了半个月C了,没想过不用中间、变量也能互换。。你们这些都哪学的啊???各位大雕。。。。!
Top
回复人:QunKangLi(To iterate is human,to recurse divine) ( 四级(中级)) 信誉:100 2005-7-20 17:25:26 得分:0
?


1. x = x ^ y ; y = y ^ x ; x = x ^ y ;
2. x = x + y ; y = x - y ; x = x - y ;
3. x = x - y ; y = y + x ; x = y - x ;
4. x = y - x ; y = y - x ; x = x + y ;
Top
回复人:i33333(Microwish_grasstalent) ( 一级(初级)) 信誉:100 2005-7-20 17:56:37 得分:0
?


我在写之前只看了楼主问题


犯得着吗


Top
回复人:VxD1(Dump) ( 二级(初级)) 信誉:100 2005-7-20 18:52:27 得分:0
?


用汇编指令XCHG就能直接交换
Top
回复人:lbing7(楼主,别再给我非专家分!谢谢合作) ( 四级(中级)) 信誉:100 2005-7-20 20:07:54 得分:0
?


能用汇编的话


寄存器也不应该算是变量吧?


用两个寄存器,几个MOV,嘿嘿


这个也行哈
Top
回复人:qingyuan18(zealot_tang) ( 五级(中级)) 信誉:99 2005-7-20 22:01:04 得分:0
?


这种面试题都烂掉牙了.
Top
回复人:awperpvip() ( 一级(初级)) 信誉:100 2005-7-20 23:45:11 得分:0
?


异或方法。
Top
回复人:guofu_x(蝈蝈) ( 二级(初级)) 信誉:100 2005-7-20 23:53:42 得分:0
?


前天也看到了这样的题目,一楼的可以说很好了,用位运算也可以.
Top
回复人:kittypizza(极光) ( 一级(初级)) 信誉:100 2005-7-21 7:01:39 得分:0
?


我靠, 沙发牛比, 以前我一直以为我的是最优的今天才知道沙发的解法,愚见:
a=(a+b)/2;
b=2*a-b;
a=2*a-b;
Top
回复人:simulationz() ( 一级(初级)) 信誉:100 2005-7-21 9:04:33 得分:0
?


使用算术运算的方法,有限制条件,需要a+b之和在MAX_INT(例如,双字节的INT 是32767)与MIN_INT(例如双字节的INT是-32768)之间。这种方法不可行。
a = a + b;
b = a - b;
a = a -b;
逻辑运算则不存在上述问题。
Top
回复人:guycs(年轻人) ( 一级(初级)) 信誉:100 2005-7-21 9:14:02 得分:0
?


做沙发的的确是最优解~~~~
Top
回复人:Feather2005(飞逸) ( 一级(初级)) 信誉:100 2005-7-21 9:43:22 得分:0
?


第一种:
a=a+b;
b=a-b;
a=a-b;


第二种:
a=a-b;
b=a+b;
a=b-a;


第三种:
a=a^b;
b=a^b;
a=a^b;
Top
回复人:Roaming_Sheep(Roaming Sheep) ( 四级(中级)) 信誉:100 2005-7-21 9:55:24 得分:0
?


异或运算的才是最优吧?
Top
回复人:dophin1003(浮云~~~) ( 二级(初级)) 信誉:100 2005-7-21 10:28:16 得分:0
?


沙发的解法有可能溢出。异或运算是最优。
Top
回复人:happysh(冰火) ( 一级(初级)) 信誉:100 2005-7-21 10:52:28 得分:0
?


最好使用指针,因为题中所说的值并非都是数值,有可能是字符串之类的。


Top
回复人:LoveCreatesBeauty(爱产生美) ( 二级(初级)) 信誉:106 2005-7-21 14:56:57 得分:0
?


http://www.cnblogs.com/lovecreatesbeauty/archive/2005/03/03/111810.html


/*
* Filename: swp_no_tmp.cpp
* Function: void swp_no_tmp(int* x, int* y);
* Purpuse : swap two numbers without a temporary variable.
* Date : 2005-3-2.
*/


#include <assert.h>
#include <stdlib.h>
#include "swp_no_tmp.h"


void swp_no_tmp(int* x, int* y){
assert((x != NULL) && (y != NULL));


*x = *x + *y;
*y = *x - *y;
*x = *x - *y;
}


Top
回复人:httpftp(我不是坏小孩儿) ( 一级(初级)) 信誉:100 2005-7-21 15:10:30 得分:0
?


C语言真是博大精深!越来越爱了!
Top
回复人:CSam() ( 一级(初级)) 信誉:100 2005-7-21 16:30:05 得分:0
?


按楼主这么说的只能是整数型的吧,字符和字符串数据能行嘛
Top
回复人:Audi_TT(人不嚣张枉少年) ( 一级(初级)) 信誉:100 2005-7-21 16:48:26 得分:0
?


mark
Top
回复人:ywchen2000(灌水大帝:努力奋斗) ( 三级(初级)) 信誉:99 2005-7-21 17:02:03 得分:0
?


一楼的有数学思想在呀
Top
回复人:xyly30(狐独男孩) ( 一级(初级)) 信誉:100 2005-7-21 21:45:03 得分:0
?


还是二楼的来得最直接,更中省事,三条语句就解决了。
Top
回复人:qifa() ( 二级(初级)) 信誉:100 2005-7-22 0:52:14 得分:0
?


a^=b^=a^=b
这是最好的方法
其他的没有考虑变量溢出的情况
Top
回复人:MagicCarmack(梦中情人C++) ( 四级(中级)) 信誉:100 2005-7-22 1:32:53 得分:0
?


a^=b^=a^=b;


高手写的语句看都要看N久才知道什么意思


Top
回复人:MagicCarmack(梦中情人C++) ( 四级(中级)) 信誉:100 2005-7-22 1:33:30 得分:0
?


但是用异或,在某些情况是行不通的!
Top
回复人:li1418(我很菜,我还笨) ( 一级(初级)) 信誉:100 2005-7-22 1:49:38 得分:0
?


你不会说这个吧?????
a=a-(b=(a=a+b)-b) ;
Top
回复人:li1418(我很菜,我还笨) ( 一级(初级)) 信誉:100 2005-7-22 1:52:29 得分:0
?


晕啊,这些人的行为。。。。。。。
哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
Top
回复人:li1418(我很菜,我还笨) ( 一级(初级)) 信誉:100 2005-7-22 1:55:24 得分:0
?


#include <iostream.h>


void main( void )
{
int a = 3;
int b = 4;
a=a-(b=(a=a+b)-b) ;


cout <<a <<" " <<b <<endl;
}
Top
回复人:ALAN_1999(学习(PHP/HTML/JS/CSS)) ( 二级(初级)) 信誉:100 2005-7-22 2:06:54 得分:0
?


mark


Top
回复人:li1418(我很菜,我还笨) ( 一级(初级)) 信誉:100 2005-7-22 2:08:19 得分:0
?


foochow(恰似你的温柔)


的是最优的,他才是真牛人,佩服佩服啊!


a^=b^=a^=b;


我认为他这个连寄存器的中间变量都不用吧??
不太懂汇编!


Top
回复人:Feather2005(飞逸) ( 一级(初级)) 信誉:100 2005-7-22 8:47:05 得分:0
?


a^=b^=a^=b
我个人觉得最好不要用这样的编码习惯,如果你在程序中大量使用这种语句,给以后维护的人员会带来多大的麻烦?一个好的编码习惯才能做一个优秀的程序员。如:++i+i++;i+++++i等的语句就BS他.
Top
回复人:improgrammer(无忌) ( 三级(初级)) 信誉:100 2005-7-22 13:54:04 得分:0
?


一楼的方法存在溢出问题,a^=b^=a^=b可以。
Top
回复人:li1418(我很菜,我还笨) ( 一级(初级)) 信誉:100 2005-7-22 14:32:54 得分:0
?


我个人觉得 Feather2005(飞逸) 说的不妥。我觉得这是对特定问题的一种处理方法而已,不能拿出这么一句就代表风格,但是这么一句可以看出实力
我还是支持 foochow(恰似你的温柔) 的a^=b^=a^=b;




improgrammer(无忌) 说的溢出问题,可以看出他也是高手哟!
Top
回复人:lovexinxin(爱欣欣) ( 一级(初级)) 信誉:100 2005-7-22 15:35:52 得分:0
?


恰似你的温柔真的超强,这个算法就算想,也要想他三年两载阿
Top
回复人:ctkevin(冰鸟) ( 一级(初级)) 信誉:100 2005-7-22 15:42:15 得分:0
?


括号里是注释
(设A=a,B=b)
a=a+b (a=A+B)
b=a+b (b=A+B+B)
a=b-a (a=(A+B+B)-(A+B)=B)
b=b-2*a (b=(A+B+B)-2*B=A)


这种的方法好呀.....易懂呀...
Top
回复人:li1418(我很菜,我还笨) ( 一级(初级)) 信誉:100 2005-7-22 16:17:04 得分:0
?


TO ctkevin(冰鸟):


易懂不敢说,但说是好方法就不敢恭维。。。。。。
Top
回复人:mic_c(贝壳撼木) ( 一级(初级)) 信誉:100 2005-7-22 22:20:51 得分:0
?


hchack(无)
a^=b^=a^=b
这是什么意思,我怎么不明白?
我也不明白
Top
回复人:llf_hust() ( 五级(中级)) 信誉:100 2005-7-22 23:59:17 得分:0
?


#include<stdio.h>
void Swap(int *a,int *b)
{
*a = *a ^ *b;
*b = *a ^ *b;
*a = *a ^ *b;
}
int main()
{
int i,j;
scanf("%d%d",&i,&j);
Swap(&i,&j);
printf("%d %d",i,j);
return 0;
}




/* 我的程序没有问题呀,输入1 2 ,输出 2 1 */




22.
主  题: c++面试题,请高人解答
作  者: liushu00 (柳树)
等  级:
信 誉 值: 100
所属论坛: C/C++ C++ 语言
问题点数: 20
回复次数: 35
发表时间: 2005-7-13 16:07:39




六、编写类String的构造函数、析构函数和赋值函数(25分)
已知类String的原型为:
class String
{
public:
String(const char *str = NULL);// 普通构造函数
String(const String &other); // 拷贝构造函数
~ String(void); // 析构函数
String & operate =(const String &other);// 赋值函数
private:
char *m_data;// 用于保存字符串
};
请编写String的上述4个函数。
回复人:FromNoWhere() ( 二级(初级)) 信誉:100 2005-7-13 16:10:57 得分:0
?


看stl源码啊.
林锐的高质量c++也有.
Top
回复人:yesiloveyou(~) ( 二级(初级)) 信誉:90 2005-7-13 16:11:41 得分:0
?


wait..
Top
回复人:hjf1010(黑色狂人) ( 二级(初级)) 信誉:100 2005-7-13 16:18:57 得分:0
?


这个网站不错,下载几本电子书看看
http://www.netyi.net/in.asp?id=hjf1010


Top
回复人:liushu00(柳树) ( 一级(初级)) 信誉:100 2005-7-13 16:21:00 得分:0
?


我现在手里没有那本书,楼上能不能帮忙贴出来?谢谢
Top
回复人:kobefly(科比---第一个项目快结束了) ( 两星(中级)) 信誉:121 2005-7-13 16:41:21 得分:0
?


// String的析构函数
String::~String(void) // 3分
{
delete [] m_data;
// 由于m_data是内部数据类型,也可以写成 delete m_data;
}


// String的普通构造函数
String::String(const char *str) // 6分
{
if(str==NULL)
{
m_data = new char[1]; // 若能加 NULL 判断则更好
*m_data = ‘\0’;
}
else
{
int length = strlen(str);
m_data = new char[length+1]; // 若能加 NULL 判断则更好
strcpy(m_data, str);
}
}
// 拷贝构造函数
String::String(const String &other) // 3分
{
int length = strlen(other.m_data);
m_data = new char[length+1]; // 若能加 NULL 判断则更好
strcpy(m_data, other.m_data);
}
// 赋值函数
String & String::operate =(const String &other) // 13分
{
// (1) 检查自赋值 // 4分
if(this == &other)
return *this;


// (2) 释放原有的内存资源 // 3分
delete [] m_data;


// (3)分配新的内存资源,并复制内容 // 3分
int length = strlen(other.m_data);
m_data = new char[length+1]; // 若能加 NULL 判断则更好
strcpy(m_data, other.m_data);


// (4)返回本对象的引用 // 3分
return *this;
}


Top
回复人:xuanwenchao(xuanwenchao) ( 二级(初级)) 信誉:100 2005-7-13 16:49:54 得分:0
?


class String
{
public:
String();
~String();
String & operator=(const String &other);
String (const String &other);
char * GetString();
private:
char *m_data;


};
char * String::GetString()
{
return m_data;
}
String & String::operator=(const String &other)
{
if(&other == this)
{
return *this;
}
m_data = new char[strlen(other.m_data)+1];
strcpy(m_data,other.m_data);
return *this;
}


String::String()
{
m_data = NULL;
return;
}
String::String (const String &other)
{
m_data = new char(strlen(other.GetString())+1);
strcpy(m_data,other.GetString());
}
String::~String()
{if(m_data != NULL)
{
delete []m_data;
}
return;
}
Top
回复人:llf_hust() ( 五级(中级)) 信誉:100 2005-7-13 16:54:25 得分:0
?


#include<iostream.h>
#include<string.h>
class String
{
public:
String(const char *str = NULL)// 普通构造函数
{
if(str==NULL)
{
m_data = new char[1]; // 若能加 NULL 判断则更好
*m_data = '\0';
}
else
{
int length = strlen(str);
m_data = new char[length+1]; // 若能加 NULL 判断则更好
strcpy(m_data, str);
}


}
String(const String &other) // 拷贝构造函数
{
int len = strlen(other.m_data);
m_data = new char[len+1];
strcpy(m_data,other.m_data);


}
virtual ~ String(void) // 析构函数
{
if(m_data)
delete []m_data;
}
String & operator =(const String &other)// 赋值函数
{


if(this == &other)
return *this;


// (2) 释放原有的内存资源 // 3分
delete [] m_data;


// (3)分配新的内存资源,并复制内容 // 3分
int length = strlen(other.m_data);
m_data = new char[length+1]; // 若能加 NULL 判断则更好
strcpy(m_data, other.m_data);


// (4)返回本对象的引用 // 3分
return *this;


}




void Display()
{
cout<<m_data<<endl;
}
private:
char *m_data;// 用于保存字符串
};
int main()
{
String a("abc"),b;
b = a;
b.Display();
return 0;
}


Top
回复人:liushu00(柳树) ( 一级(初级)) 信誉:100 2005-7-13 16:57:29 得分:0
?


谢谢大家帮忙
Top
回复人:thuers(我什么都不会,所以我想多看看) ( 二级(初级)) 信誉:100 2005-7-13 16:58:52 得分:0
?


yun ~!


这题~!
Top
回复人:liushu00(柳树) ( 一级(初级)) 信誉:100 2005-7-13 17:06:27 得分:0
?


再问一下:为什么用string & other,而不用string other,有什么区别?
Top
回复人:xuanwenchao(xuanwenchao) ( 二级(初级)) 信誉:100 2005-7-13 17:09:59 得分:0
?


string other 会拷贝一个副本
string & other 不会拷贝(省去了构造新的对象的时间还节省了内存空间)
Top
回复人:pantian(白天傻子) ( 一级(初级)) 信誉:94 2005-7-13 17:22:45 得分:0
?


yun ~!


这题~!
==============================


这题是不是你们公司出的???呵呵,我刚刚被人面试了这个题目,好像也是第6题(反正是最后一题),好像也是25分,还说总分没有60分,就不会有第二轮面试。


真的很恶心这个题目的。faint,其实满世界都是答案,要不,大家在Google上搜索一下。


个人感觉这种题目面试不出别人的能力。真的,如果你让我去MS写API函数的实现,面试这种题目还可以。
就是写些应用程序,用得着如此嘛,而且说是面试C++,整套题目就这一个是面向对象的。太需要运气了,如果我这个题没答对,就能说明我面向对象没学好?说明我的C++没学好?


反正我后来也没拿到60分,郁闷呀。
Top
回复人:visual4825() ( 二级(初级)) 信誉:100 2005-7-13 18:35:17 得分:0
?


回复人: liushu00(柳树) ( ) 信誉:100 2005-07-13 17:06:00 得分: 0




再问一下:为什么用string & other,而不用string other,有什么区别?




--------------------------------------------------
string other: call copy constructor, infinite loop
Top
回复人:xiabao(小军) ( 一级(初级)) 信誉:100 2005-7-13 18:48:49 得分:0
?


高质量C++
Top
回复人:whatsouta(某疯子) ( 二级(初级)) 信誉:100 2005-7-13 18:55:44 得分:0
?


visual4825() 正解


如果不是引用的话,它会去调用复制构造函数初始化形参,就成了自己调用自己的死循环了。


Top
回复人:nuaa3(alan) ( 一级(初级)) 信誉:100 2005-7-13 19:28:08 得分:0
?


mark
Top
回复人:Extreme007(Extreme007) ( 一级(初级)) 信誉:100 2005-7-13 21:05:15 得分:0
?


关于为什么用string &other 而不用 string other 的区别?


个人认为...因为此类定义的私有成员是一个字符指针涉及到内存地址问题.


因为在把对象当作实参传递时...对象会生成一个临时副本.是实参的一个副本.这个副本的内容与实参一模一样,也就是实参的私有成员*m_data与副本的私有成员*m_data同指向一块内存地址.而副本传递结束时会销毁.相应的实参的*m_data的值也就丢失了.这是问题的关键所在.(实际传递时的是对象的副本)所以此处用的是引用..用引用就会解决这个问题,当实参在传递的过程中不会产生副本的现象.
本人认为(产生对象副本)不太好理解,比较抽象的一个问题...我也是个初学者水平有限.
也是由于这个问题导致C++中的"复制构造函数"的产生
Top
回复人:MagicCarmack(梦中情人C++) ( 四级(中级)) 信誉:100 2005-7-13 23:35:44 得分:0
?


林锐 高质量C++
Top
回复人:zsx123(我要活下去) ( 二级(初级)) 信誉:100 2005-7-14 10:44:38 得分:0
?


String(const String &other) // 拷贝构造函数
{
cout<<other.m_data; //????????????
int len = strlen(other.m_data);
m_data = new char[len+1];
strcpy(m_data,other.m_data);


}
cout<<other.m_data;//m_data是other对象的私有数据,怎么可以这样得到呢?请指教。
Top
回复人:mihonghang(弭米) ( 一级(初级)) 信誉:100 2005-7-14 10:46:27 得分:0
?


晕 这个代码很多吧 ??林锐的 高质量开发 下了 看看吧。
Top
回复人:llf_hust() ( 五级(中级)) 信誉:100 2005-7-14 10:50:52 得分:0
?


String(const String &other) // 拷贝构造函数
{
cout<<other.m_data; //????????????
int len = strlen(other.m_data);
m_data = new char[len+1];
strcpy(m_data,other.m_data);


}
cout<<other.m_data;//m_data是other对象的私有数据,怎么可以这样得到呢?请指教。
/* 类的成员函数当然可以访问类的私有数据 */
Top
回复人:zsx123(我要活下去) ( 二级(初级)) 信誉:100 2005-7-14 10:59:42 得分:0
?


cout<<other.m_data;//m_data是other对象的私有数据,怎么可以这样得到呢?请指教。
/* 类的成员函数当然可以访问类的私有数据 */
--------------------------------------------------
但m_data并没有通过other实例的成员函数访问的呀?而是直接用了other.m_data,谢谢指教!!!


像如下的例子:
class string
{
private:
int a;


public:
string()
{
a=1;
}
};


void main()
{
string mystring;
cout<<mystring.a;
}
Top
回复人:zsx123(我要活下去) ( 二级(初级)) 信誉:100 2005-7-14 11:09:02 得分:0
?


明白了,谢了
Top
回复人:chengjr(小小) ( 一级(初级)) 信誉:100 2005-7-14 11:28:31 得分:0
?


恩 考这个题的就是垃圾
我也做过这个题,可惜当时在赋值函数中忘了delete原来的内存:(
他们能不能考点新颖的
Top
回复人:shuihan84(shuihan84) ( 一级(初级)) 信誉:100 2005-7-14 11:45:30 得分:0
?


又是林锐的题
Top
回复人:netfloator(Adam Lee) ( 一级(初级)) 信誉:100 2005-7-14 12:38:01 得分:0
?


#include<iostream.h>
#include<string.h>
class String
{
public:
String(const char *str = NULL)// 普通构造函数
{
if(str==NULL)
{
m_data = new char[1]; // 若能加 NULL 判断则更好
*m_data = '\0';
}
else
{
int length = strlen(str);
m_data = new char[length+1]; // 若能加 NULL 判断则更好
strcpy(m_data, str);
}


}
String(const String &other) // 拷贝构造函数
{
int len = strlen(other.m_data);
m_data = new char[len+1];
strcpy(m_data,other.m_data);


}
virtual ~ String(void) // 析构函数
{
if(m_data)
delete []m_data;
}
String & operator =(const String &other)// 赋值函数
{


if(this == &other)
return *this;


// (2) 释放原有的内存资源 // 3分
delete [] m_data;


// (3)分配新的内存资源,并复制内容 // 3分
int length = strlen(other.m_data);
m_data = new char[length+1]; // 若能加 NULL 判断则更好
strcpy(m_data, other.m_data);


// (4)返回本对象的引用 // 3分
return *this;


}




void Display()
{
cout<<m_data<<endl;
}
private:
char *m_data;// 用于保存字符串
};
int main()
{
String a("abc"),b;
b = a;
b.Display();
return 0;
}


Top
回复人:hanfeichunan(化脓的阑尾) ( 三级(初级)) 信誉:98 2005-7-14 14:24:57 得分:0
?


全部都是垃圾,异常安全没一个
Top
回复人:CSDNWW(中国软件WW) ( 一级(初级)) 信誉:100 2005-7-14 17:03:27 得分:0
?


>>String & operate =(const String &other);// 赋值函数
题目都出错了!应是:
String & operator =(const String &other);// 赋值函数


Top
回复人:CSDNWW(中国软件WW) ( 一级(初级)) 信誉:100 2005-7-14 17:04:11 得分:0
?


>>String & operate =(const String &other);// 赋值函数
题目都错了, 是operator!!
Top
回复人:whatsouta(某疯子) ( 二级(初级)) 信誉:100 2005-7-14 18:55:42 得分:0
?


String(const String &other) // 拷贝构造函数
{
cout<<other.m_data; //这里要调用公共方法访问,不能直接访问。
int len = strlen(other.m_data);
m_data = new char[len+1];
strcpy(m_data,other.m_data); //这里要调用公共方法访问,不能直接访问。


}
cout<<other.m_data;//m_data是other对象的私有数据,怎么可以这样得到呢?请指教。
/* 类的成员函数当然可以访问类的私有数据 */






Top
回复人:xjp6688(大平/要做必须最好) ( 四级(中级)) 信誉:100 2005-7-15 0:03:16 得分:0
?


这种题挺基础
Top
回复人:zzm7000() ( 二级(初级)) 信誉:100 2005-7-15 2:22:22 得分:0
?


这几天面试题特别多哈
Top
回复人:psc88() ( 一级(初级)) 信誉:100 2005-7-15 9:25:36 得分:0
?


高质量编程中全部都有的啊
Top
回复人:mikewolfli(冰峰雪古) ( 一级(初级)) 信誉:100 2005-7-15 13:12:08 得分:0
?


是不是又照搬林锐的《c++高质量编程》后的习题啊^_^
Top
回复人:sunlu_eric(天使预备役) ( 二级(初级)) 信誉:100 2005-7-16 15:32:28 得分:0
?


String(const String &other) // 拷贝构造函数
{
cout<<other.m_data; //这里要调用公共方法访问,不能直接访问。
int len = strlen(other.m_data);
m_data = new char[len+1];
strcpy(m_data,other.m_data); //这里要调用公共方法访问,不能直接访问。


}
cout<<other.m_data;//m_data是other对象的私有数据,怎么可以这样得到呢?请指教。
/* 类的成员函数当然可以访问类的私有数据 */
就是,因为他是成员函数呀,默认的this指针那!




23.
 
CSDN - 专家门诊 - C/C++ C++ 语言问题
回复 | 推荐 | 收藏 | 专题 | 公告 | 管理 | 加入FAQ | 关闭窗口
主  题: 来者有分,今天的一道面试题
作  者: jiajun2001 (嘉俊)
等  级:
信 誉 值: 100
所属论坛: C/C++ C++ 语言
问题点数: 100
回复次数: 72
发表时间: 2005-7-13 21:03:53




今天面试,一道程序设计题,实现发牌算法。一共52张牌,没有大小王。我大概作了一下,下面的是我后来后整理的完整版本,和我面试的时候差不多。不能够使用STL。
#include<iostream>


using namespace std;


struct PK_Link
{
char *PK;
PK_Link *next;
} *Header, *ptr;


void CreatePK( char *p )
{
Header = new PK_Link;
Header->PK = p;
Header->next = NULL;
ptr = Header;
}


void AddPK( char *p )
{
PK_Link *PK = new PK_Link;
PK->PK = p;
PK->next = Header;
ptr->next = PK;
ptr = ptr->next;
}


char* FindPK( int i )
{
while( i > 0 )
{
--i;
ptr = ptr->next;
}
return ptr->next->PK;
}


void DeletePK()
{
PK_Link *t = ptr->next;
ptr->next = ptr->next->next;
delete t;
}


void DestroyPK()
{
delete ptr;
}


char *PKD[52] = {
"黑桃A", "红桃A", "方块A", "梅花A",
"黑桃2", "红桃2", "方块2", "梅花2",
"黑桃3", "红桃3", "方块3", "梅花3",
"黑桃4", "红桃4", "方块4", "梅花4",
"黑桃5", "红桃5", "方块5", "梅花5",
"黑桃6", "红桃6", "方块6", "梅花6",
"黑桃7", "红桃7", "方块7", "梅花7",
"黑桃8", "红桃8", "方块8", "梅花8",
"黑桃9", "红桃9", "方块9", "梅花9",
"黑桃10", "红桃10", "方块10", "梅花10",
"黑桃J", "红桃J", "方块J", "梅花J",
"黑桃Q", "红桃Q", "方块Q", "梅花Q",
"黑桃K", "红桃K", "方块K", "梅花K"
};


char *Persion[4][13] = {0};




int main( int argc, char *argv[] )
{
int i = 0, j = 0, k = 0;
CreatePK( PKD[0] );
for ( ; i < 51; i++ )
{
AddPK( PKD[i] );
}
i = 52;
while( i > 1 )
{
Persion[j][k] = FindPK( rand() % i );
DeletePK();
--i;
++j;
if ( j > 3 )
{
++k;
j = 0;
}
}
Persion[3][12] = FindPK( 1 );
for ( j = 0; j < 4; j++ )
{
cout<<"Persion["<<j+1<<"]";
for( k = 0; k < 13; k++ )
{
cout<<" "<<Persion[j][k];
}
cout<<endl;
}
DestroyPK();
return 0;
}


大家看看,我能通过吗?谁还有更好的算法!
回复人:qfeng_zhao(天天向上) ( 三级(初级)) 信誉:100 2005-7-13 21:10:09 得分:1
?


没问题
Top
回复人:durkingzhang(永胜) ( 一级(初级)) 信誉:100 2005-7-13 21:46:16 得分:1
?


虽然没有错误,但是一般!!!!!!
Top
回复人:AntonlioX(做人要厚道) ( 一级(初级)) 信誉:100 2005-7-13 21:47:29 得分:1
?


mark
Top
回复人:chengjr(小小) ( 一级(初级)) 信誉:100 2005-7-13 21:51:58 得分:1
?


你从来不写注释的吗
我实在不想看没注释的代码,好歹也说说你的思路
Top
回复人:yangbc(土豆块) ( 一级(初级)) 信誉:100 2005-7-13 21:53:40 得分:1
?


没看你的程序,不过你只要用了随机数就应该差不多了,只要从前往后把数组中的牌跟一个随机出现的位置的牌互换,然后再把这些牌发到玩家手中就可以了
Top
回复人:god_sun(孙大帅哥) ( 一级(初级)) 信誉:100 2005-7-13 21:57:32 得分:1
?


是啊 ,楼主写写注释吧:)
Top
回复人:WecanHuang(曾阿牛) ( 一级(初级)) 信誉:100 2005-7-13 22:05:05 得分:1
?


现在的面试。。。
Top
回复人:K() ( 二级(初级)) 信誉:100 2005-7-13 22:12:13 得分:1
?


怎么发都是一样的牌
Top
回复人:jiajun2001(嘉俊) ( 二级(初级)) 信誉:100 2005-7-13 22:16:29 得分:0
?


我在面试的卷子上写了设计思路!
使用一个单向循环链表,从头指针开始,随机向前移动,取出牌,删除这个节点,然后继续作。直道取出52张牌!
Top
回复人:boxban(冻酸梨) ( 五级(中级)) 信誉:100 2005-7-13 22:19:29 得分:10
?


恕我直言,你的实现从功能上可能没有问题,但代码实现也有点太罗嗦了。


你没有详细说明题目,不知道除了STL,还有没有其他限制?是不是指定了必须要使用链表来实现?
如果仅仅是实现“将不含大小王的52张扑克牌随机发给4个人,并显示发牌的最终结果”的功能,应该是很简单的。代码应该可以实现得更简洁、高效。


下面是我的一个实现。
另外,楼主在开始没有调用srand()设置随机种子,导致楼上所说的“怎么发都是一样的牌”的问题。
=========================================================================================
#include <stdio.h>
#include <stdlib.h>
#include <time.h>




//
// 我给出的是一种相对节省“空间”的实现。
// 如果将52张牌的花色、名称全部保存在数组中(如楼主的实现),
// 则可以简化牌面的显示并获得最大的运行时性能。
//
//数字 0~51 代表52张扑克牌。
//每连续13张为同一花色的13张牌,如黑桃A~黑桃K(如 CARD_NAME 定义)。
//花色以 "黑桃", "红桃", "方块", "梅花" 顺序排列(如 COLOR_NAME 定义)
//
static const char* CARD_NAME[] = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};
static const char* COLOR_NAME[] = { "黑桃", "红桃", "方块", "梅花" };
static const int COLORS = sizeof(COLOR_NAME)/sizeof(COLOR_NAME[0]);
static const int CARDS = sizeof(CARD_NAME)/sizeof(CARD_NAME[0]);


static const int N = 52;
static const int CARD_USED = 0;


//发牌
void dispatch_cards(int out[N])
{
int cards[N];
int i, t;


for (i = 0; i < N; ++i) cards[i] = i + 1; //设置牌号
for (i = 0; i < N;){
t = (rand() % N);
if (cards[t] != CARD_USED){
cards[t] = CARD_USED;
out[i++] = t;
}
}
}


//显示牌面
void show_cards(const int cards[N])
{
int i, j;


//0~12, 13~25, ... 分别存放4个人牌
for (i = 0; i < N;){
printf("\nPerson %d: ", i / CARDS + 1);
for (j = 0; j < CARDS; ++j, ++i)
printf("%s%s, ", COLOR_NAME[cards[i] / CARDS], CARD_NAME[cards[i] % CARDS]);
}
}


int main(int argc, char agrv[])
{
int cards[N];


srand(time(NULL));
dispatch_cards(cards);
show_cards(cards);


return 0;
}


Top
回复人:jiajun2001(嘉俊) ( 二级(初级)) 信誉:100 2005-7-13 22:46:47 得分:0
?


兄弟,空间效率有了,时间效率差了!
Top
回复人:vsfan(窘) ( 二级(初级)) 信誉:105 2005-7-13 23:28:20 得分:1
?


呵呵
其实数组也可以模拟的
Top
回复人:MagicCarmack(梦中情人C++) ( 四级(中级)) 信誉:100 2005-7-13 23:30:30 得分:1
?


数组模拟可行
Top
回复人:wiali(维埃里) ( 一级(初级)) 信誉:99 2005-7-14 0:29:58 得分:1
?


我觉得应该考的是随机算法的编写,而不掉系统函数显示一下那么简单。
Top
回复人:wiali(维埃里) ( 一级(初级)) 信誉:99 2005-7-14 1:11:59 得分:3
?


我认为时间效率肯定是boxban(冻酸梨)的高,这个链表分配查找和删除肯定没数组来得快。


另外我觉得boxban(冻酸梨)写的非常简洁,而且没有hardcode,相比之下,楼主hardcode很明显.


挺佩服boxban(冻酸梨)的代码的,找了半天没找到一句废码,唯一可以改进的地方就是:


static const int CARD_USED = 0; =》static const int CARD_USED = 1;
int cards[N]; =》int cards[N]={0};


最后 for (i = 0; i < N; ++i) cards[i] = i + 1; 这句话就可以不要了,这样还可以省掉一句话。


我也就是瞎扯,大家只当听个乐呵!


Top
回复人:mayingbao(网络游侠) ( 一级(初级)) 信誉:100 2005-7-14 6:13:14 得分:1
?


你没有详细说明题目,不知道除了STL,还有没有其他限制?是不是指定了必须要使用链表来实现?
如果仅仅是实现“将不含大小王的52张扑克牌随机发给4个人,并显示发牌的最终结果”的功能,应该是很简单的
Top
回复人:sea2000cn(我想我是海) ( 二级(初级)) 信誉:100 2005-7-14 7:22:21 得分:1
?


用数组模拟是不是更快?
Top
回复人:aayy(以后我不用这个名字了) ( 一级(初级)) 信誉:100 2005-7-14 8:28:48 得分:1
?


做个标记
Top
回复人:jiajun2001(嘉俊) ( 二级(初级)) 信誉:100 2005-7-14 8:49:31 得分:0
?


感谢大家!boxban的方法固然不错,但是还是有很多缺陷,并不是最优解法。还有其他人吗?
Top
回复人:sy_lyx(沈阳之最)(阿轩) ( 一级(初级)) 信誉:100 2005-7-14 8:59:39 得分:1
?


No problem.
Top
回复人:lonelyforest(一生所爱) ( 二级(初级)) 信誉:100 2005-7-14 9:14:29 得分:1
?


老兄们啊, 为什么不用类呢??
Top
回复人:jiajun2001(嘉俊) ( 二级(初级)) 信誉:100 2005-7-14 9:34:34 得分:0
?


我给的基本上就是原题了,大家自由发挥!
Top
回复人:boxban(冻酸梨) ( 五级(中级)) 信誉:100 2005-7-14 9:48:13 得分:1
?


感谢大家!boxban的方法固然不错,但是还是有很多缺陷,并不是最优解法。还有其他人吗?
===================================================================================
首先感谢楼主的表扬,呵呵。
对于很多问题,多数情况下并不存在所谓的“最优解法”。我想大家都知道“时间换空间,空间换时间”的法则;对于不用的应用环境、硬件环境,可能需要采取不同的策略。
我的实现采取了“时间换空间”的策略,相对于将52张牌面全部保存在数组的解法而言虽然节省的空间只有区区几十个字节,但理还是这个理,呵呵


楼主称我的方法有很多缺陷,能否具体讲讲?死也得让我死个明白呀 ^_^
Top
回复人:login__whf(还买烟不*_*) ( 一级(初级)) 信誉:100 2005-7-14 10:19:34 得分:1
?


up
Top
回复人:xuanwenchao(xuanwenchao) ( 二级(初级)) 信誉:100 2005-7-14 10:43:42 得分:1
?


我觉得boxban(冻酸梨)的算法已经不错了.
Top
回复人:jiajun2001(嘉俊) ( 二级(初级)) 信誉:100 2005-7-14 10:48:59 得分:0
?


to boxban
是这样的,作为随机数,是允许有重复值出现的,那么在这里
for (i = 0; i < N;){
t = (rand() % N);
if (cards[t] != CARD_USED){
cards[t] = CARD_USED;
out[i++] = t;
}
}
必然会浪费一些时间,而且这个时间浪费还会随着i值的不断增大而增大,因为可用的太少了。
是否考虑N要变化,把它规定在一个符合52-i内的范围之内,这样会避免一些时间浪费!


这是我对你的程序的一点分析!
Top
回复人:syg1() ( 一级(初级)) 信誉:100 2005-7-14 11:11:15 得分:5
?


#include <iostream.h>
int Poker[52];


//&frac12;&laquo;start+1&micro;&frac12;end&micro;&Auml;&Aring;&AElig;&Iuml;ò&Ccedil;°&Ograve;&AElig;&para;&macr;&Ograve;&raquo;&Icirc;&raquo;
void movepoker(int Poker[],int start,int end)
{
int i=0;
for (i=start;i<end-1; i++)
{
Poker[i]= Poker[i+1];
}
}


void dispatch() //Poker[52]&Ouml;&ETH;--->0-12 &Ecirc;&Ccedil;&micro;&Uacute;&Ograve;&raquo;&cedil;&ouml;&Egrave;&Euml; 13-25&Ecirc;&Ccedil;&micro;&Uacute;&para;&thorn;&cedil;&ouml;&Egrave;&Euml; 26 - 38&Ecirc;&Ccedil;&micro;&Uacute;&Egrave;&yacute;&cedil;&ouml;&Egrave;&Euml; 39 - 51 &Ecirc;&Ccedil;&micro;&Uacute;&Euml;&Auml;&cedil;&ouml;&Egrave;&Euml;&micro;&Auml; &Aring;&AElig;
{
int i=0;
int rand=0;
int pokernum = 52;
int index =0;
int Tpoker[52];


//&frac12;&laquo;52&Otilde;&Aring;&Aring;&AElig;·&Aring;&Egrave;&euml;&Ecirc;&yacute;×éTpoker&Ouml;&ETH;,·&cent;&Aring;&AElig;&micro;&Auml;&Ecirc;±&ordm;ò&acute;&Oacute;&Ouml;&ETH;&Egrave;&iexcl;&sup3;&ouml;
for(i=0;i<pokernum;i++)
{
Tpoker[i] = i;
}


//start to ·&cent;&Aring;&AElig;
index =0;
while(pokernum){
rand = rand();
rand %= pokernum; //&Ocirc;&Uacute;0&micro;&frac12;pokernum-1&sup2;ú&Eacute;ú&Ograve;&raquo;&cedil;&ouml;&Euml;&aelig;&raquo;ú&Ecirc;&yacute;


Poker[index++] = Tpoker[rand]; //&Egrave;&iexcl;&sup3;&ouml;&Ocirc;&Uacute;&acute;&Euml;&acute;&brvbar;&micro;&Auml;&Ecirc;&yacute;×&Ouml;


//rand&Icirc;&raquo;&Ouml;&Atilde;&micro;&Auml;&Aring;&AElig;&Ograve;&Ntilde;&frac34;&shy;&Egrave;&iexcl;&sup3;&ouml;,&frac12;&laquo;rand+1&micro;&frac12;pokernum-1&Iuml;ò&Ccedil;°&Ograve;&AElig;&Ograve;&raquo;&Icirc;&raquo;
movepoker(Tpoker,rand,pokernum-1);
//&Ecirc;&pound;&Oacute;à&micro;&Auml;&Aring;&AElig;&Ecirc;&yacute;&frac14;&otilde;1
pokernum--;
}
}
Top
回复人:junnyfeng(风歌) ( 一星(中级)) 信誉:107 2005-7-14 11:11:15 得分:1
?


boxban(冻酸梨) 的程序比较巧妙,是让人有耐心去看的程序!
Top
回复人:junnyfeng(风歌) ( 一星(中级)) 信誉:107 2005-7-14 11:12:19 得分:1
?


搂主是不是姓邓?
Top
回复人:iamltd(妖) ( 一级(初级)) 信誉:100 2005-7-14 11:15:07 得分:1
?


生成随机数那里是需要技巧的


循环改成:
i=N-1;
do{
t=(rand() % i--);c=0;
do{
if(cards[c] !=CARD_USED)c++;
}while(c<t)
cards[c] = CARD_USED;
out[i]=t;
}while(i>=0)


这样处理以后,每次生成的随机数不再是牌的序号,而是未发的牌的序号。可以保证不会产生冲突。
理论上的时间效率很低,实际运行中应该是最优时间算法了。
--------------------------------------------
语法上大概没错吧。呵呵,我一向记不清语法的。
Top
回复人:boyu_song(I'm sorry) ( 一级(初级)) 信誉:100 2005-7-14 11:15:47 得分:1
?


I'm use the JAVA,and this program ,you can use the JAVABEAN,that will be easier~
Top
回复人:jiajun2001(嘉俊) ( 二级(初级)) 信誉:100 2005-7-14 11:27:55 得分:0
?


to junnyfeng(风歌) 为什么怎么问?
Top
回复人:jiajun2001(嘉俊) ( 二级(初级)) 信誉:100 2005-7-14 11:29:43 得分:0
?


我不姓邓阿!
Top
回复人:jiajun2001(嘉俊) ( 二级(初级)) 信誉:100 2005-7-14 11:34:51 得分:0
?


to iamltd(妖)
你的程序有错误!
因为使用了随机数,不能随意作i--,所以你的程序发不出52张牌!
Top
回复人:simec(simec) ( 一级(初级)) 信誉:100 2005-7-14 11:35:11 得分:1
?


gz
Top
回复人:yvhkdragon(剑客) ( 二级(初级)) 信誉:100 2005-7-14 12:24:06 得分:1
?


UP
Top
回复人:netfloator(Adam Lee) ( 一级(初级)) 信誉:100 2005-7-14 12:39:21 得分:1
?


AddPK中好像有问题,字符串赋值要用strcpy,直接用指针赋值会有问题。
还有*PKD[52]数组不用罗列出来,可以在程序中给他们赋值。
存储扑克可以用顺序表,删除牌时,不必用顺序表的删除算法,只要把这个元素与第i(就是你程序中用到的i)个元素交换即可。
Top
回复人:jiajun2001(嘉俊) ( 二级(初级)) 信誉:100 2005-7-14 13:08:40 得分:0
?


楼上的,这只是对指针操作。
如果在程序中赋值的话,简单的指针操作就不行了!
Top
回复人:jiajun2001(嘉俊) ( 二级(初级)) 信誉:100 2005-7-14 13:10:54 得分:0
?


你那个交换的方法非常好!呵呵!还有谁阿!~
Top
回复人:qingyuan18(zealot_tang) ( 四级(中级)) 信誉:99 2005-7-14 13:40:28 得分:1
?


boxban(冻酸梨)的发排方法相当于每个人从洗好的牌中随机抽13张,而jiajun2001 (嘉俊) 的发排方法是最常见的四个人依次每人一张
Top
回复人:sinall(走或留,这是个问题) ( 一级(初级)) 信誉:100 2005-7-14 14:13:20 得分:1
?


其实就是STL中的洗牌算法,洗好了牌,大家一揭牌不就完事了。
凭直觉,感觉boxban(冻酸梨)的方法确实好,但也有提升时间复杂度的可能。
待俺去研究研究。
Top
回复人:boxban(冻酸梨) ( 五级(中级)) 信誉:100 2005-7-14 14:18:15 得分:1
?


to boxban
是这样的,作为随机数,是允许有重复值出现的,那么在这里
for (i = 0; i < N;){
t = (rand() % N);
if (cards[t] != CARD_USED){
cards[t] = CARD_USED;
out[i++] = t;
}
}
必然会浪费一些时间,而且这个时间浪费还会随着i值的不断增大而增大,因为可用的太少了。
是否考虑N要变化,把它规定在一个符合52-i内的范围之内,这样会避免一些时间浪费!


这是我对你的程序的一点分析!
========================================
"是否考虑N要变化,把它规定在一个符合52-i内的范围之内"
这是不可行的。
按照你的说法,假设第一次 t = 10, 然后 i++,在第二次循环时令 N = N - i = 51。
那么,你就再也没有机会取道51号扑克牌了




Top
回复人:jiajun2001(嘉俊) ( 二级(初级)) 信誉:100 2005-7-14 14:49:00 得分:0
?


我只是这个意思,并不是一定那样,当然会出现你上面所说的问题了!
Top
回复人:OMA_yudy(太平洋深深) ( 一级(初级)) 信誉:100 2005-7-14 15:15:24 得分:15
?


#include <iostream.h>
#include <stdlib.h>
#include <time.h>


#define N 52
struct joke {
char p[4];
};


joke page[52] = {"S1","S2","S3","S4","S5","S6","S7","S8","S9","S10","S11","S12","S13",
"H1","H2","H3","H4","H5","H6","H7","H8","H9","H10","H11","H12","H13",
"D1","D2","D3","D4","D5","D6","D7","D8","D9","D10","D11","D12","D13",
"C1","C2","C3","C4","C5","C6","C7","C8","C9","C10","C11","C12","C13",};


void exchange(int a[])
{
srand( (unsigned)time( NULL ) );
int tmp,v;
for (int i=0;i<52;i++)
{
v = rand()%N;
if(i!=v){
tmp = a[v];
a[v] = a[i];
a[i] = tmp;
}
}
for (i=0;i<52;i++)
{
cout.width(3);
cout<<page[(a[i]-1)].p<<" ";
if (i==52 || i==12 || i==25 || i==38)
{
cout<<endl;
}
}
}




int main(int argc, char* argv[])
{
int na[52];
for (int i=0;i<52;i++)
{
na[i]=i+1;
}


exchange(na);


cout<<endl;


char tmp;
cin>>tmp;
return 0;
}




从浪费时间的角度出发
Top
回复人:jiajun2001(嘉俊) ( 二级(初级)) 信誉:100 2005-7-14 15:32:17 得分:0
?


OMA_yudy的差不多时间复杂度和空间复杂度有所保证了
Top
回复人:hewittlee(只爱C++) ( 二级(初级)) 信誉:100 2005-7-14 15:59:47 得分:1
?


不错!
Top
回复人:seann_liu() ( 一级(初级)) 信誉:100 2005-7-14 16:57:37 得分:3
?


#include <iostream.h>
#include <iomanip.h>
#include <stdlib.h>
#include <time.h>


void shuffle ( int [] [13] );
int main()
{
const char *suit[4]={"Heart", "Diamonds", "Clubs", "spades"};
const char *face[13] = {"Ace", "Deuce", "Three", "Four", "Five", "Six", "Seven",
"Eight", "Nine", "Ten", "Jack", "Queen", "King"};
int deck[4][13] = {0};
srand (time(0));
shuffle(deck);
deal (deck, face, suit);
return 0;
}


void shuffle (int wDeck[][13])
{
int row, column;
for (int card = 1; card <=52; card++){
do {
row = rand()%4;
column = rand()%13;
}while (wDeck[row][column] != 0);
wDeck[row][column] = card;
}
}


void deal (const int wDeck[][13], const char *wDeck[], const char *wSuit[])
{
for (int card = 1; card <=52; card++)


for (int row = 0; row <=3; row ++)


for (int column = 0; column <= 12; column++)
if (wDeck [row][column] == card)


cout << setw(5) << setiosflags(ios::right)
<< wFace[column] << "of"
<<setw(8) << setiosflags(ios::left)<<wSuit[row]
<< (card % 2 == 0 ? '\n' : '\t';
}
Top
回复人:seann_liu() ( 一级(初级)) 信誉:100 2005-7-14 17:27:38 得分:1
?


不过这个程序应该有一点点小毛病
Top
回复人:foochow(恰似你的温柔) ( 五级(中级)) 信誉:100 2005-7-14 17:33:28 得分:1
?


洗好牌在发出去?
Top
回复人:seann_liu() ( 一级(初级)) 信誉:100 2005-7-14 17:51:18 得分:1
?


no,是deal那个function....
Top
回复人:tslkfyh(TSL) ( 一级(初级)) 信誉:100 2005-7-14 18:31:19 得分:1
?


程序开始时把牌创建成一个链(供以后多次发牌使用)
使用一个记数器(如I=52)
产生大小在记数器范围内的随机数
根据此数在链中打位置(如标置了已发的不算一个位置 例如 1未发->2未发->3已发->4未发->5未发,现在随机数为3 找到的是4未发)发牌;
标致已发,记数器减一;


不知思路有没有用
Top
回复人:seann_liu() ( 一级(初级)) 信誉:100 2005-7-14 18:51:07 得分:1
?


思路是酱子,我没说思路,我的意思是我觉得我的代码的最后一部分好像有点小毛病...
Top
回复人:yangwuhan(*冰点*) ( 二级(初级)) 信誉:100 2005-7-14 19:00:10 得分:1
?


jf
Top
回复人:jiajun2001(嘉俊) ( 二级(初级)) 信誉:100 2005-7-14 20:05:37 得分:0
?


to seann_liu()
你的代码有做无用功的时候,跟boxban(冻酸梨)的一样!
目前OMA_yudy(太平洋深深) 的最好
Top
回复人:jiangbo1125(江小鱼) ( 一级(初级)) 信誉:100 2005-7-14 20:19:24 得分:1
?


是用链表实现的吗?
Top
回复人:jiajun2001(嘉俊) ( 二级(初级)) 信誉:100 2005-7-14 20:32:00 得分:0
?


我使用的单向循环链表
Top
回复人:seann_liu() ( 一级(初级)) 信誉:100 2005-7-14 20:34:37 得分:1
?


我知道有作无用功的时候,你能帮改一下吗?
Top
回复人:jiajun2001(嘉俊) ( 二级(初级)) 信誉:100 2005-7-14 20:57:00 得分:0
?


参考OMA_yudy(太平洋深深)的代码
Top
回复人:seann_liu() ( 一级(初级)) 信誉:100 2005-7-14 21:00:41 得分:3
?


或者这样:
#include <iostream.h>
#include <iomanip.h>
#include <stdlib.h>
#include <time.h>




struct Card{
char *face;
char *suit;
};


void fillDeck (Card*, char *[], char *[]);
void shuffle(Card *);
void deal (Card *);


int main()
{
Card deck[52];
char *face[13] = {"Ace", "Deuce", "Three", "Four", "Five", "Six", "Seven",
"Eight", "Nine", "Ten", "Jack", "Queen", "King"};
char *suit[] = {"Hearts", "Diamonds", "Clubs", "Spades"};
srand(time(0));
fillDeck (deck, face, suit);
shuffle(deck);
deal (deck);
return 0;
}


void fillDeck(Card *wDeck, char *wFace[], char *wSuit[])
{
for (int i = 0; i < 52; i++){
wDeck[i].face = wFace[i % 13];
wDeck[i].suit = wSuit[i / 13];
}
}


void shuffle (Card *wDeck)
{
for (int i = 0; i < 52; i++){
int j = rand() % 52;
Card temp = wDeck[i];
wDeck[i] = wDeck[j];
wDeck[j] = temp;
}
}


void deal (Card *wDeck)
{
for ( int i = 0; i <52; i++)
cout<< setiosflags(ios::right)<<setw(5)<<wDeck[i].face<<"of"<<setiosflags(ios::left)<<setw(8)<<wDeck[i].suit<<((i+1) % 2 ? '\t' : '\n');
Top
回复人:seann_liu() ( 一级(初级)) 信誉:100 2005-7-14 21:16:51 得分:1
?


这次应该好啦,哈哈^_^
Top
回复人:Atramentous_boy(黑色男孩) ( 一级(初级)) 信誉:100 2005-7-14 21:37:07 得分:1
?


这个程序不是很难,在电子工业出的《C++大学教程》是例题!呵呵~
主要是用来实验随机数的!
Top
回复人:fangrk(加把油,伙计!) ( 两星(中级)) 信誉:125 2005-7-14 22:09:44 得分:10
?


以前写过,现在找不到了。


int array[N];//48张牌按照一定的顺序存放
...
for(int i=0;i<N;++i){
int k=[0,N)之间的一个随机数;
if(k!=N-i-1) 交换array[i]和array[k];
}
输出array


或者
int array[N];//48张牌按照一定的顺序存放
...
random_shuffle(array,array+N);//可以查看STL用法
Top
回复人:jiajun2001(嘉俊) ( 二级(初级)) 信誉:100 2005-7-14 22:40:25 得分:0
?


楼上的,不准使用STL
不过你前面给的效果不错!
Top
回复人:fangrk(加把油,伙计!) ( 两星(中级)) 信誉:125 2005-7-15 8:58:22 得分:5
?


#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int main()
{
const char* Num="2 3 4 5 6 7 8 9 10J Q K A ";
const char* Color="SHDC";//四种花色
const int N=13,C=4;
int Array[N*C];
int f=0;
for(int i=0;i<N;++i){
for(int j=0;j<C;++j){
Array[f++]=(i<<2)+j;
}
}
cout<<"牌号\t花色\n";
time_t t;
srand((unsigned) time(&t));
while(--f>=0){
int index=rand()%(f+1);
int Nindex=Array[index]>>2,Cindex=Array[index]&3;
cout<<Num[Nindex*2]<<Num[Nindex*2+1]<<'\t'<<Color[Cindex]<<'\n';
if(index!=f){
int t=Array[index];
Array[index]=Array[f];
Array[f]=t;
}
}
system("pause");
}




#include <iostream>
#include <algorithm>
#include <ctime>
#include <cstdlib>
using namespace std;
int main()
{
const char* Num="2 3 4 5 6 7 8 9 10J Q K A ";
const char* Color="SHDC";
const int N=13,C=4;
int Array[N*C];
int f=0;
for(int i=0;i<N;++i){
for(int j=0;j<C;++j){
Array[f++]=(i<<2)+j;
}
}
cout<<"牌号\t花色\n";
time_t t;
srand((unsigned) time(&t));
random_shuffle(Array,Array+f);
while(--f>=0){
int Nindex=Array[f]>>2,Cindex=Array[f]&3;
cout<<Num[Nindex*2]<<Num[Nindex*2+1]<<'\t'<<Color[Cindex]<<'\n';
}
system("pause");
}
Top
回复人:jiajun2001(嘉俊) ( 二级(初级)) 信誉:100 2005-7-15 9:11:07 得分:0
?


好了,开始结贴
Top
回复人:K() ( 二级(初级)) 信誉:100 2005-7-15 9:12:04 得分:1
?


xuexi
Top
回复人:sinall(走或留,这是个问题) ( 一级(初级)) 信誉:100 2005-7-15 9:19:24 得分:1
?


回复人: iamltd(妖) ( ) 信誉:100 2005-7-14 11:15:07 得分: 0






生成随机数那里是需要技巧的


循环改成:
i=N-1;
do{
t=(rand() % i--);c=0;
do{
if(cards[c] !=CARD_USED)c++;
}while(c<t)
cards[c] = CARD_USED;
out[i]=t;
}while(i>=0)


这样处理以后,每次生成的随机数不再是牌的序号,而是未发的牌的序号。可以保证不会产生冲突。
理论上的时间效率很低,实际运行中应该是最优时间算法了。
--------------------------------------------
语法上大概没错吧。呵呵,我一向记不清语法的。


—————————————————————————————————————————————
可以考虑,第一次抽的牌和第52张交换
第二次抽的牌和第51张交换
……
那么上面的算法应该可以保证了。


Top
回复人:psc88() ( 一级(初级)) 信誉:100 2005-7-15 9:19:43 得分:1
?


学习啊!!!!!!
Top
回复人:CSDNWW(中国软件WW) ( 一级(初级)) 信誉:100 2005-7-15 17:16:31 得分:1
?


**************
int i = 0, j = 0, k = 0;
CreatePK( PKD[0] );
for ( ; i < 51; i++ )
{
AddPK( PKD[i] );
}
********
楼主这段代码明显有问题了, 创建从PKD[0]开始, 添加又是从PKD[0]开始
Top
回复人:CSDNWW(中国软件WW) ( 一级(初级)) 信誉:100 2005-7-15 17:40:57 得分:1
?


srand( (unsigned)time( NULL ) );
这句这么重要的不能省
Top
回复人:CSDNWW(中国软件WW) ( 一级(初级)) 信誉:100 2005-7-15 17:53:11 得分:1
?


**********************
char* FindPK( int i )
{
while( i > 0 )
{
--i;
ptr = ptr->next;
}
********************
即然是循环链表, 为了移够i位而移, 蛮搞笑的
Top
回复人:jiajun2001(嘉俊) ( 二级(初级)) 信誉:100 2005-7-15 20:57:13 得分:0
?


楼上的,怎么搞笑了?
Top


该问题已经结贴 ,得分记录: qfeng_zhao (1)、 durkingzhang (1)、 AntonlioX (1)、 chengjr (1)、 yangbc (1)、 god_sun (1)、 WecanHuang (1)、 K (1)、 boxban (10)、 vsfan (1)、 MagicCarmack (1)、 wiali (1)、 wiali (3)、 mayingbao (1)、 sea2000cn (1)、 aayy (1)、 sy_lyx (1)、 lonelyforest (1)、 boxban (1)、 login__whf (1)、 xuanwenchao (1)、 syg1 (5)、 junnyfeng (1)、 junnyfeng (1)、 iamltd (1)、 boyu_song (1)、 simec (1)、 yvhkdragon (1)、 netfloator (1)、 qingyuan18 (1)、 sinall (1)、 boxban (1)、 OMA_yudy (15)、 hewittlee (1)、 seann_liu (3)、 seann_liu (1)、 foochow (1)、 seann_liu (1)、 tslkfyh (1)、 seann_liu (1)、 yangwuhan (1)、 jiangbo1125 (1)、 seann_liu (1)、 seann_liu (3)、 seann_liu (1)、 Atramentous_boy (1)、 fangrk (10)、 fangrk (5)、 K (1)、 sinall (1)、 psc88 (1)、 CSDNWW (1)、 CSDNWW (1)、 CSDNWW (1)、




24.
主  题: 今天的面试题,实在郁闷。
作  者: cybernik ()
等  级:
信 誉 值: 99
所属论坛: C/C++ C语言
问题点数: 100
回复次数: 68
发表时间: 2005-7-4 19:21:00




今天去面试写一个C程序~~结果没搞定,大家帮忙看看~~~大家动动脑竟啊,不那么简单的~~~
篮球比赛共有4节比赛,得分分别为3(胜),1(平),0(负),总比分从70(70以下算做一种情况)到120(120以上算做一种情况),
问A队对B对的胜负情况共有多少种?~~~
提示:就是比如A队得3,3,1,0,并且得90分,B队0,0,1,3得80分为其中一种情况;A队得3,3,1,0,并且得91分,B队0,0,1,3 得80分为其中一种情况;A队得3,3,1,0,并且得99分,B队0,0,1,3得81分为其中一种情况....................................................
结果:205483。
死也要也要死得明白~~~100分想送~~~!!!!
回复人:cybernik() ( 一级(初级)) 信誉:99 2005-7-4 19:22:35 得分:0
?


大家都来看看撒~~~
Top
回复人:ningzhiyu(凝滞雨) ( 四级(中级)) 信誉:100 2005-7-4 19:40:42 得分:0
?


看不明白……
Top
回复人:cybernik() ( 一级(初级)) 信誉:99 2005-7-4 19:54:42 得分:0
?


就是判断同时必须要小节总比分和总得分都大的情况~~全部统计出来~~
Top
回复人:ningzhiyu(凝滞雨) ( 四级(中级)) 信誉:100 2005-7-4 20:06:34 得分:0
?


应该是排列问题吧。
穷举所有可能情况,判断。




Top
回复人:cybernik() ( 一级(初级)) 信誉:99 2005-7-4 20:10:24 得分:0
?


楼上的XD,正是如此,能否做一下试试?
Top
回复人:xiaoluoli(C/C++思考) ( 三级(初级)) 信誉:98 2005-7-4 20:38:59 得分:0
?


应该是“堆排序问题” 数据结构 排序那章(选择排序这方面的内容) 应该是
因为堆排序算法就是根据打球的比赛规则推出来的
Top
回复人:cybernik() ( 一级(初级)) 信誉:99 2005-7-4 20:53:19 得分:0
?


哎~~~先回家了~~~明天在来~~~先贴上我写的代码,郁闷~~~~
#include <stdio.h>


int main()
{
unsigned int a=0, b=0, c=0, d=0, m=70,n=70,count=0;
unsigned int j=0,k=0,x=0,y=0;
int total_a=0,total_b=0;
for( a = 0;a<3; a++)
{
j=2-a;
for( b = 0; b<3; b++)
{
k=2-b;
for( c = 0; c <3; c++)
{
x=2-c;
for( d= 0; d<3; d++)
{
y=2-d;
for (m = 70 ; m<120; m++)
{
for (n = 70 ; n <120; n++)
{
total_a=a+b+c+d;
total_b=j+k+x+y;
if(total_a>total_b&&m>n)
{
count++;
printf("[1],total_a:%d,total_b:%d____m:%d,m:%d_____count:%d\n",total_a,total_b,m,n,count);
}
if(total_a==total_b&&m==n)
{
count++;
printf("[2],total_a:%d,total_b:%d____m:%d,m:%d_____count:%d\n",total_a,total_b,m,n,count);
}
if(total_a<total_b&&m<n)
{
count++;
printf("[3],total_a:%d,total_b:%d____m:%d,m:%d_____count:%d\n",total_a,total_b,m,n,count);
}
}
}
}
}
}
}






printf("%ld", count);
return 0;
}
Top
回复人:wiali(维埃里) ( 一级(初级)) 信誉:99 2005-7-4 21:01:55 得分:0
?


我手算一下,瞎算的,大家来批判:
A队 在四节比赛中分别可以有三种情况:3*3*3*3 = 81种,在A定了的这种情况下B的每节输赢肯定是定了的。
每场比赛输赢定了的情况下还有分数可变,所以总比分A有3种,B有3种,那么应该是3*3=9
所以最后可能性有:81*9 = 729种啊


哪来的205483啊,搞不懂啊!
Top
回复人:wiali(维埃里) ( 一级(初级)) 信誉:99 2005-7-4 21:03:26 得分:0
?


哦,对不起,忘了算平的情况下的了
Top
回复人:zsh6709(世界上没有后悔药吃的!!!) ( 二级(初级)) 信誉:100 2005-7-4 21:14:43 得分:0
?


回复人: cybernik() ( ) 信誉:99
这位老兄给的代码,我看不懂,请教!!!
Top
回复人:cybernik() ( 一级(初级)) 信誉:99 2005-7-4 21:30:00 得分:0
?


to wiali(维埃里)
是小节分数和比分的组合
Top
回复人:jiangbo1125(江小鱼) ( 一级(初级)) 信誉:100 2005-7-4 21:39:52 得分:0
?


好难呀!看不懂
Top
回复人:MUTOUWU(郑屠) ( 一级(初级)) 信誉:100 2005-7-4 22:24:37 得分:0
?


哈哈,这个看不懂题意,篮球赛不是以最后的总得分算输赢么,什么时候搞那么复杂了
Top
回复人:LordSimon(LordSimon) ( 一级(初级)) 信誉:100 2005-7-4 22:31:43 得分:0
?


啊...没见过这么变态的...我还以为程序员是为了简化人们的生活而存在的
Top
回复人:wiali(维埃里) ( 一级(初级)) 信誉:99 2005-7-4 23:42:07 得分:0
?


是不是这个意思:


小节分数(只有输、赢、平三种)是决定A或B队输赢的,只要A的四个小节分数之和大于B的四个小节分数之和,就算A赢了; 但是在输赢定了的情况下总比分可以不同的,知道A赢的总分大于B的总分就可以了,不可能A的总分100,B的总分90这样赢也算一种情况吧!


先讨论小节定输赢:A胜B
A; 3,1,1,1 B: 0,1,1,1 --A赢一场(其它全平)这里开树叉(平,全,输)
A; 3,3,1,1 B: 0,0,1,1 --A赢两场(其它全平)这里开树叉(平,全,输)
A; 3,3,3,0 B: 0,0,0,1 --A赢三场(其它全平)这里开树叉(平,全,输)
A; 3,3,3,3 B: 0,0,0,0 --A赢四场
.
.
.


再讨论总分胜出应该有的情况:A胜B
A: <70 不可能
A; >=70 && <=120 B: <70
A: >120 B: <70 或 >=70 && <=120




反正这个问题绝对是一个数据结构的树的搜索剪枝 求胜的情况下的路径问题


Top
回复人:wiali(维埃里) ( 一级(初级)) 信誉:99 2005-7-5 0:00:32 得分:0
?


我觉得上来就建树,三叉树,从第一节开始开3个叉(因为A的输赢平都决定了B的输赢平),然后对每一个开叉的节点做下一节的输赢平开三叉,树一共有5层,每层是一节比赛(根节点),接着剪枝,根据4节比赛加起来的小节分值过滤掉一些路径。


最后在这些所以路径里再开叉,就是每个叉有三种总分可能,接着再次剪枝过滤(见上面分析),最后剩下的就是符合条件的各种情况了。


随便瞎说,只是探讨
Top
回复人:wiali(维埃里) ( 一级(初级)) 信誉:99 2005-7-5 0:01:55 得分:0
?


刚才错了,每层是一节比赛(除了根节点)
Top
回复人:andy_bin(乐逍遥) ( 二级(初级)) 信誉:100 2005-7-5 0:02:23 得分:0
?




不懂!


友情 up!


Top
回复人:wiali(维埃里) ( 一级(初级)) 信誉:99 2005-7-5 0:08:02 得分:0
?


对不起,我理解错了,总分有 0(60以下),70,71......120, 1000(120以上)这么多种情况可取
Top
回复人:wiali(维埃里) ( 一级(初级)) 信誉:99 2005-7-5 0:35:48 得分:0
?


列出条件:


a1+b1+c1+d1 > a2+b2+c2+d2 赢 (a1,b1,c1,d1,a2,b2,c2,d2从1-4循环)
a2 = a1;(a1==1)
a2 = abs(a1-3) (a1!=1)


b2 = b1;(b1==1)
b2 = abs(b1-3) (b1!=1)


.
.
.


然后把结果的个数记下来,分数是总分和小节没有任何关系,只要知道总的输赢就可以了,所以再另开循环(两个for从70-120),最外面的循环是刚才求的赢结果数字,这样就可以算出所有的组合了


Top
回复人:cybernik() ( 一级(初级)) 信誉:99 2005-7-5 9:18:11 得分:0
?


to wiali(维埃里)
XD说的有道理,不知道你的最后结果得出来是多少?
Top
回复人:liuhaimiao() ( 一级(初级)) 信誉:100 2005-7-5 11:15:19 得分:0
?


NBA也没有这种打法吧,是谁出的题目?懂不懂篮球?!
Top
回复人:cizhenxin() ( 一级(初级)) 信誉:100 2005-7-5 12:04:40 得分:0
?


友情UP
Top
回复人:cizhenxin() ( 一级(初级)) 信誉:100 2005-7-5 12:13:32 得分:0
?


得分分别为3(胜),1(平),0(负),
提示:就是比如A队得3,3,1,0,并且得90分,B队0,0,1,3得80分为其中一种情况;
这里没有搞清楚楼主或是哪个GGJJ给提示一下




Top
回复人:cizhenxin() ( 一级(初级)) 信誉:100 2005-7-5 12:21:36 得分:0
?


哦对不起题目看错了
理解错了!!!


Top
回复人:clamy(克莱明) ( 一级(初级)) 信誉:100 2005-7-5 13:43:02 得分:0
?


x1:y1=15:15,x2:y2=16:15,x3:y3=16:15,x4:y4=16:15,sumX:sumY=63:60


x1:y1=15:15,x2:y2=16:15,x3:y3=16:15,x4:y4=27:26,sumX:sumY=74:71


x1:y1=15:15,x2:y2=16:15,x3:y3=16:15,x4:y4=28:26,sumX:sumY=75:71


x1:y1=15:15,x2:y2=16:15,x3:y3=16:15,x4:y4=28:27,sumX:sumY=75:72


x1:y1=15:15,x2:y2=16:15,x3:y3=16:15,x4:y4=29:26,sumX:sumY=76:71


x1:y1=15:15,x2:y2=16:15,x3:y3=16:15,x4:y4=29:27,sumX:sumY=76:72


x1:y1=15:15,x2:y2=16:15,x3:y3=16:15,x4:y4=29:28,sumX:sumY=76:73


x1:y1=15:15,x2:y2=16:15,x3:y3=16:15,x4:y4=30:26,sumX:sumY=77:71


x1:y1=15:15,x2:y2=16:15,x3:y3=16:15,x4:y4=30:27,sumX:sumY=77:72


x1:y1=15:15,x2:y2=16:15,x3:y3=16:15,x4:y4=30:28,sumX:sumY=77:73


依照楼主给出的题意,我大致列出几种情况...(满足:3胜,1平,0负)


请问楼主: 我以上列出的几种情况算否? (其中:x1,x2,x3,x4分别表示A队1-4节得分,sumX为总得分;B队用y表示)


如果你认为是成立的话, 那满足题意的可能性非常大 远多于你给的答案!


Top
回复人:hoya5121(C++农民) ( 一级(初级)) 信誉:100 2005-7-5 13:44:41 得分:0
?


up下吧
Top
回复人:cizhenxin() ( 一级(初级)) 信誉:100 2005-7-5 14:54:13 得分:0
?


平和其它情况(120-70)+1+2
胜负2*(X)
设想X为A胜
A可以得71到120不等B只能得到70到119不等
排列组合
设指针I表示A的得分[71,120]J<=I[70 119]用一个双重循环也许可以..
这是两个内循环
外循环是可列的几种情况
但在这里只能看A胜的情况这里不好了解怎么去评判,怎么样去算A胜了(比如A可能前三节都负但是最后一节大比分胜)我想除去(0和1)的组合外A都可以取胜
这种组合下来可能和答案差不了多少吧
现在要考试这只是一个设想不知道对或是不对
高手帮评一下谢谢
Top
回复人:Eric1952() ( 一级(初级)) 信誉:100 2005-7-5 15:06:45 得分:0
?


这个问题好像不要用复杂程序还算
#include <iosteam>
using namespace std;
void main()
{
cout<<51*(51*81-51*2);
}
结果:205479
至于还有4中到哪里去了?不知道。
Top
回复人:Eric1952() ( 一级(初级)) 信誉:100 2005-7-5 15:23:27 得分:0
?


如:A得70分,B得分可能有51种情况,每种得分情况对应的节得分情况有3的四次方种,减去两种情况:如总分平则没有0,0,0,0和3,3,3,3两种情况,A的分数有51种情况。
Top
回复人:Eric1952() ( 一级(初级)) 信誉:100 2005-7-5 15:29:18 得分:0
?


/******总比分从70(70以下算做一种情况)到120(120以上算做一种情况)****/
两队都为“70”或“120”时,节得分情况有3的四次方种,此为特例,不要减去上述两种情况
所以
结果为:205479+2*2=205483
Top
回复人:Willpro(WillPro) ( 一级(初级)) 信誉:100 2005-7-5 15:55:03 得分:0
?


不会!
Top
回复人:z19820201(waysun) ( 一级(初级)) 信誉:100 2005-7-5 20:20:39 得分:0
?


//将小于70的情况用作分值69代替,大于120的情况用121代替。


#include <iostream>


using namespace std;




int main()
{
unsigned i, j, k, m;
unsigned long total = 0;
unsigned win, loss, equal;
for( i = 0; i < 3; i++ )
for( j = 0; j < 3; j++ )
for ( k = 0; k < 3; k++ )
for ( m = 0; m < 3; m++ )
{
win = loss = equal = 0;
if ( i == 2 ) win++;
if ( j == 2 ) win++;
if ( k == 2 ) win++;
if ( m == 2 ) win++;
if ( i == 1 ) equal++;
if ( j == 1 ) equal++;
if ( k == 1 ) equal++;
if ( m == 1 ) equal++;
if ( i == 0 ) loss++;
if ( j == 0 ) loss++;
if ( k == 0 ) loss++;
if ( m == 0 ) loss++;


if ( loss > 0 ) // 输了,只要输一节就能输掉总分
total += 1378;//有可能的比分为120:121; 119:120,119:121; ...
//一共是1+2+3+...+(121-69)=1378种比分。


if ( ( win > 0 && loss > 0 ) || equal == 4 ) // 平局,有输有赢或者全平的时候才有可能是平局
total += 53;//平局只有69:69,70:70,...121:121共53中情况。


if ( win > 0 ) // 赢了
total += 1378;




}


cout << total << endl;


system( "pause" );


return 0;
}


我的结果只有181843。不知道哪些情况没有考虑到。
Top
回复人:lgxysl(我心欲静) ( 一级(初级)) 信誉:100 2005-7-6 0:12:43 得分:0
?


private void button1_Click(object sender, System.EventArgs e)
{
long p=0;
for(int i1=0;i1<=2;i1++)
{
for(int i2=0;i2<=2;i2++)
{
for(int i3=0;i3<=2;i3++)
{
for(int i4=0;i4<=2;i4++)
{
if(i1*i2*i3*i4!=1 && i1*i2*i3*i4!=16 && i1+i2+i3+i4!=0)//不全平且不全输的情况
{
for(int j1=69;j1<=121;j1++)
{
for(int j2=69;j2<=121;j2++)//(如3330,70;0003,120;这实际上不可能,但从题意的理论上是可能的.如4场的比分分别是:30:0; 30:0; 10:0; 0:120)
{
p=p+1;
}
}
}
}
}
}
}
p=p+(121-69)+1;//全平的情况
for(int k1=69;k1<=117;k1++)//有一队全输的情况
{
for(int k2=k1+4;k2<=121;k2++)//全输的一队至少要少4个球
{
p=p+2;//有可能A全输,也有可能B全输
}
}
textBox1.Text =""+p;
}


看不出我错在哪里,但就是得不到205483.我的结果是221605.
请高手指教!
另外,题意也有些不清楚,例如不知是这样:
A队:得分3,3,3,0;积分70以下;B队:0,0,0,3;积分70,属其中的一种情况
A队:得分3,3,3,0;积分70以下;B队:0,0,0,3;积分71,属其中的另一种情况


还是:
凡是有一队积分低于70的,属一种情况,即上述的两种情况只属于一种情况.


Top
回复人:kgdiwss(∮明天去要饭) ( 一级(初级)) 信誉:95 2005-7-6 0:18:11 得分:0
?


晕,这考的是算法啊。
Top
回复人:z19820201(waysun) ( 一级(初级)) 信誉:100 2005-7-6 9:37:40 得分:0
?


to lgxysl(我心欲静):
你的算法在情况只有赢平或只有输平的时候多算了。
比如:比分3311,可有的情况为
for(int k1=69;k1<=121-2;k1++)
for(int k2=k1+2;k2<=121;k2++)
p++;
而你的算法中有
for(int k1=69;k1<=121;k1++)
for(int k2=k1;k2<=121;k2++)
p++;


Top
回复人:lgxysl(我心欲静) ( 一级(初级)) 信誉:100 2005-7-6 10:11:03 得分:0
?


to: z19820201(waysun)
-----------------------------------------------
对,今天早我在未年到你的贴前我已经知道了这一点,我也改了算法,但是仍得不到楼主的结果.
不知道楼主的结果是对的还是错的!!!
也许楼主贴出的结果是他自己的结果,根本就是错的(所以面试不过关),对的楼主也不知道.
请楼主解释一下!


Top
回复人:lgxysl(我心欲静) ( 一级(初级)) 信誉:100 2005-7-6 10:12:07 得分:0
?


更正:
年到--->看到
Top
回复人:z19820201(waysun) ( 一级(初级)) 信誉:100 2005-7-6 11:43:49 得分:0
?


假设楼主是对的,则只有一个人分析出来了,编程出来的结果没有一个是对的。我把lgxysl(我心欲静)的程序改了一下,结果为180089。反正不一样,程序我就不贴出来了。
Top
回复人:lgxysl(我心欲静) ( 一级(初级)) 信誉:100 2005-7-6 11:48:53 得分:0
?


to:z19820201(waysun)
_____________________________________________________
呵呵!楼主不知到哪里去了.现在这台戏变成我们两个在唱啦!
等下班我把我的程序改一改,看看又是多少?
(现在不能,现在正在上班,偷偷的上网,一听到脚步声要立即关IE)


Top
回复人:daseny(胡杨) ( 二级(初级)) 信誉:100 2005-7-6 12:55:21 得分:0
?


我觉得楼主的答案有些大。


这个题本质上应该是考虑在各种总分下可能的小节胜负。
70到120总共51个可用分,则可能的总分共有51*51种;
没种总分下,每节可以有3种(胜负平)情形,四节可以有3*3*3*3种;
总计毛有51*51*3*3*3*3=210681种。
这需要排除不合理项,包括总分不同小节全平的,包括总分A>B各小节却是A<=B的。
A>B共有51(50+0)/2种,每种B>=A的情形有2*2*2*2种,加上B>A的同样数目,
共计51*50*16=40800种。
那么剩下的,至多210681-40800=169881种了。


不保证正确,大家讨论^_^
Top
回复人:ltc_mouse(野地芳菲) ( 三级(初级)) 信誉:100 2005-7-6 14:33:20 得分:0
?


赞同楼上的思想,不过具体分析时似乎不是很完整:


对于A>B,我觉得应该分以下几种情况讨论:
A=B+1 不可能每节A<=B(2^4);同时不可能出现{3,3,1,1}、{3,3,3,1}、{3,3,3,3}等
合计 2^4 + C(4,2) + C(4,3) + C(4,4)
A=B+2 2^4 + C(4,3)+C(4,4) ---不可能出现{3,3,3,1}等
A=B+3 2^4 + C(4,4) ---不可能出现{3,3,3,3}
A>=B+4 2^4
Top
回复人:lgxysl(我心欲静) ( 一级(初级)) 信誉:100 2005-7-6 15:00:39 得分:0
?


现在给出我修改后的代码.这样的面试题真有点复杂.
private void button1_Click(object sender, System.EventArgs e)
{
textBox1.Text ="";
textBox1.Text =""+Px();
}


private long Px()
{
long p=0;
//历遍所有胜负的可能,这应该没有错的,除非理解题意错了
for(int i1=0;i1<=2;i1++)
{
for(int i2=0;i2<=2;i2++)
{
for(int i3=0;i3<=2;i3++)
{
for(int i4=0;i4<=2;i4++)
{
p=p+Ps(i1,i2,i3,i4);//按不同的胜负计算总比分的可能组合,这是问题的关键所在
}
}
}
}
return p;
}


private long Ps(int i1,int i2,int i3,int i4)
{
long P=0;
if(i1*i2*i3*i4==0 && (i1==2 || i2==2 || i3==2 || i4==2))
//互有输赢的情况,这种情况总比分可任意组合
//在互有输赢的情况下,i1->i4中必有一个为0,也必有一个为2
{
for(int k1=69;k1<=121;k1++)//历遍所有可能
{
for(int k2=69;k2<=121;k2++)
{
P=P+1;
}
}
}
else
{
if(i1*i2*i3*i4==1)//全平,两队的总比分必须相同
{
P=121-69+1;//其实为53种可能
}
else//既不互有输赢,又不全平,则必为一方赢或平,一方输或平
//此时赢方的总比分必须大于输方
//这种情况有4种可能
//1.赢一场,其余平,则胜方至少比负方总比分多1个球
//2.胜两场,其余平,则胜方至少比负方总比分多2个球
//余类推
{
double Pl=Math.Log(i1*i2*i3*i4,2);//计算胜方胜出的场数
if (Pl>=1 && Pl<=4)//只按胜方计算
{
for(double k1=69;k1<=121;k1++)//历遍所有可能
{
if(k1+Pl<121)
{
for(double k2=k1+Pl;k2<=121;k2++)
{
P=P+2;//两队可以互为胜方,故+2
}
}
else
{
P=P+2;//胜队总比分在121以上,负队在121以下的情况
}
}
}
}
}
return P;
}


以上代码用C#编写,运自正常,得出的结果为180153,与楼主的不同.
楼主,你的是否就是正确的标准答案呀?????!!!
Top
回复人:lgxysl(我心欲静) ( 一级(初级)) 信誉:100 2005-7-6 15:07:37 得分:0
?


假设楼主是对的,则只有一个人分析出来了,编程出来的结果没有一个是对的。我把lgxysl(我心欲静)的程序改了一下,结果为180089。反正不一样,程序我就不贴出来了。
________________________________________________________________
发现一个很奇怪的现象(我用的是C#).
我上面的代码,如果按F5启动,结果是180153.如果按Ctrl+F5启动,结果有时是180089,有时是180153.而生成Exe后运行,永远是180153.真是奇怪.
不知调试与不调式启动有什么区别.
大侠们继续呀!
Top
回复人:z19820201(waysun) ( 一级(初级)) 信誉:100 2005-7-6 16:01:43 得分:0
?


对C#没有研究。我用VC6.0。
将我自己的程序又改了一下。结果还是180089。
程序如下:
//将小于70的情况用作分值69代替,大于120的情况用121代替。


#include <iostream>


using namespace std;




int main()
{
unsigned i, j, k, m;
unsigned long total = 0;
unsigned win, loss, equal;
for( i = 0; i < 3; i++ )
for( j = 0; j < 3; j++ )
for ( k = 0; k < 3; k++ )
for ( m = 0; m < 3; m++ )
{
win = loss = equal = 0;
if ( i == 2 ) win++;
if ( j == 2 ) win++;
if ( k == 2 ) win++;
if ( m == 2 ) win++;
if ( i == 1 ) equal++;
if ( j == 1 ) equal++;
if ( k == 1 ) equal++;
if ( m == 1 ) equal++;
if ( i == 0 ) loss++;
if ( j == 0 ) loss++;
if ( k == 0 ) loss++;
if ( m == 0 ) loss++;
if ( loss > 0 ) // 输了,只要输一节就能输掉总分
if ( win == 0 )
for ( int i1 = 69; i1 <= 121 - loss; i1++ )
for ( int i2 = i1 + loss; i2 <= 121; i2++ )
total++;
else
for ( int i1 = 69; i1 <= 121; i1++ )
for ( int i2 = 69; i2 <= 121; i2++ )
if( i1 < i2 ) total++;


if ( ( win > 0 && loss > 0 ) || equal == 4 ) // 平局
totale += 121 - 69 + 1;


if ( win > 0 ) // 赢了
if ( loss == 0 )
for ( int i1 = 121; i1 >= 69 + win; i1-- )
for ( int i2 = i1 - win; i2 <= 121 - win; i2++ )
total++;
else
for ( int i1 = 69; i1 <= 121; i1++ )
for ( int i2 = 69; i2 <= 121; i2++ )
if( i1 > i2 ) total++;
}


cout << total<< endl;


system( "pause" );


return 0;
}


Top
回复人:z19820201(waysun) ( 一级(初级)) 信誉:100 2005-7-6 16:08:26 得分:0
?


这是我修改的lgxysl(我心欲静)的程序
#include <iostream>


using namespace std;


int main()
{
long p = 0;
int i1,i2,i3,i4,j1,j2;
for(i1=0;i1<=2;i1++)
for(i2=0;i2<=2;i2++)
for(i3=0;i3<=2;i3++)
for(i4=0;i4<=2;i4++)
{
int mc = i1 * i2 * i3 * i4;
int mc1 = i1%2 || i2%2 || i3%2 || i4%2;
int mc2 = i1/2 + i2/2 + i3/2 + i4/2;
int mj = i1 + i2 + i3 + i4;


if ( mc == 1) //全平
p += ( 121 - 69 ) + 1;


else if ( mc == 16 || mj == 0) //全赢或全输
for ( int k1 =121; k1 >= 69+4; k1-- )
for ( int k2 = k1 - 4; k2 <= 121-4; k2++ )
p++;


else if ( mc != 0 ) //只有赢平
for ( j1 = 121; j1 >=69 + mc2; j1-- )
for ( j2 = 69; j2 <= j1 - mc2; j2++)
p++;


else if ( mc2 == 0 )//只有输平
for ( j1 = 69; j1 <=121 - (4-mj); j1++ )
for ( j2 = j1 + (4-mj); j2 <= 121; j2++)
p++;


else if ( mc1 != 1 )//只有输赢
for( j1=69;j1<=121;j1++)
for( j2=69;j2<=121;j2++)
p++;


else //输赢平
for( j1=69;j1<=121;j1++)
for( j2=69;j2<=121;j2++)
p++;




}


cout << p << endl;


return 0;
}
Top
回复人:winzz123(忙啊盲) ( 一级(初级)) 信誉:100 2005-7-6 16:51:57 得分:0
?


我狂顶一下!但是题我都没看懂!惭愧啊!
Top
回复人:xhl_dir(I'am 小强!) ( 一级(初级)) 信誉:100 2005-7-6 17:38:15 得分:0
?


哥们,我理解你,因为我没看懂题目.
这个题目要考的点是什么啊?? 这才是重要的!!!
是聪明才智还是别的什么?????
友情 UP 一下
下次好运!!!!
Top
回复人:Rod_xmn(小于) ( 一级(初级)) 信誉:100 2005-7-6 17:47:47 得分:0
?


讲一下思路,不知道对不对。
首先用穷举法得到所有的A可能得到的四节比赛成绩。
得到一个四位数的数组。除去其中所有的1,如果得到的新的数组。
如果数组为空,说明a和b平。情况有53种。
如果数组和为0,说明a输,情况为1+2+3+。。。。。+52;
如果数组和为(3*数组长度)。情况为1+2+。。。。+52;
其他:情况为53*53。
全部相加。就是答案。
Top
回复人:login__whf(还买烟不*_*) ( 一级(初级)) 信誉:100 2005-7-6 17:50:46 得分:0
?


mark
Top
回复人:cjnet(孤星剑) ( 二级(初级)) 信誉:100 2005-7-6 18:13:51 得分:0
?


有意思,关注!!
Top
回复人:lgxysl(我心欲静) ( 一级(初级)) 信誉:100 2005-7-6 18:31:47 得分:0
?


按:


1、互有胜负。这种情况总比分没有限制,即使有一队输3场,胜一场,它的总比分仍有可能大于胜3场负1场的。如(20:10,20:10,20:10,10:60)这时甲为 3330,总比分70;乙为0003,但总比分却为80。所以,在有胜有负的情况下,对总比分没的限制。


2、全部打平。这时总比分两必须相等。这种情况只有53种可能。


3、一方为胜,其余打平(可细分为胜1场平3场,胜2场平2场,胜3场平1场,胜4场)。这种情况下,胜方的总比分必然大于负方,而且大出的数量必然要大于或等于胜出的场数,如A比B胜2场(其余平),B的总比分为70,那么A的总比分必然要大于或等于72(因为胜出的两场至少每场要胜1分吧)


这样分类应该是正确的,既于结果,我的结果与 z19820201(waysun)已基本一致,只是可能有一些更细节的问题没有处理好。


Top
回复人:ply6669747(阿七) ( 一级(初级)) 信誉:100 2005-7-6 18:34:41 得分:0
?


看看先
Top
回复人:microleft() ( 一级(初级)) 信誉:100 2005-7-6 18:41:31 得分:0
?


205483这个答案有疑问
lgxysl(我心欲静)
-------------------------
1、互有胜负。这种情况总比分没有限制,即使有一队输3场,胜一场,它的总比分仍有可能大于胜3场负1场的。如(20:10,20:10,20:10,10:60)这时甲为3330,总比分70;乙为0003,但总比分却为80。所以,
在有胜有负的情况下,对总比分没的限制。


2、全部打平。这时总比分两必须相等。这种情况只有53种可能。


3、一方为胜,其余打平(可细分为胜1场平3场,胜2场平2场,胜3场平1场,胜4场)。这种情况下,胜方的总比分必然大于负方,而且大出的数量必然要大于或等于胜出的场数,如A比B胜2场(其余平),B的总比分为70,那么A的总比分必然要大于或等于72(因为胜出的两场至少每场要胜1分吧)


这样分类应该是正确的,既于结果,我的结果与 z19820201(waysun)已基本一致,只是可能有一些更细节的问题没有处理好。
-------------------------
补充一下,3.一方为胜,其余打平...
如果负方为70以下时,胜方可以为任意分数
如果胜方为120以上时,负方可以为任意分数


这样答案为180219...不知道对否?


Top
回复人:cunsh(找工作) ( 一级(初级)) 信誉:100 2005-7-6 18:44:50 得分:0
?


没看懂题.郁闷.理解能力弱.
楼长能不能把题说的清楚一些.求什么?
或者哪位读懂题目了能把题目贴一下好吗?


Top
回复人:lgxysl(我心欲静) ( 一级(初级)) 信誉:100 2005-7-6 18:59:51 得分:0
?


这个问题好像不要用复杂程序还算
#include <iosteam>
using namespace std;
void main()
{
cout<<51*(51*81-51*2);
}
结果:205479
至于还有4中到哪里去了?不知道。


如:A得70分,B得分可能有51种情况,每种得分情况对应的节得分情况有3的四次方种,减去两种情况:如总分平则没有0,0,0,0和3,3,3,3两种情况,A的分数有51种情况。


/******总比分从70(70以下算做一种情况)到120(120以上算做一种情况)****/
两队都为“70”或“120”时,节得分情况有3的四次方种,此为特例,不要减去上述两种情况
所以
结果为:205479+2*2=205483
——————————————————————————————————————————
我认真分析了上面这位仁兄的分析,按这位仁兄的分析,他得出了楼主给出的答案。表面上来说,他的分析是正确的,但一细推敲,发觉这位仁兄的算法却是错的!
上面这位仁兄只对全负(或全胜)作了特殊处理,没有对胜平作出特殊处理。


“如 A得70分,B得分可能有51种情况,每种得分情况对应的节得分情况有3的四次方种,减去两种情况:如总分平则没有0,0,0,0和3,3,3,3两种情况,A的分数有51种情况。”这种说法是错的,显然,对于A得分70,B得分80,下面的节得分是不可能的3、1、1、1和0、1、1、1,即对于这种得分情况,节得分种数不对应于3的4次方。


以这种错误的算法,得出了205483这个结果,所以205483这个答案的正确与否,确实值得怀疑!!!!!!!


楼主不见了,楼到快来说说205483是否就是标准答案?!




Top
回复人:lgxysl(我心欲静) ( 一级(初级)) 信誉:100 2005-7-6 19:05:46 得分:0
?


从考查点上来看,这个问题的重点应该是在于考面试者对问题的分析能力。
Top
回复人:cunsh(找工作) ( 一级(初级)) 信誉:100 2005-7-6 19:28:10 得分:0
?


哪位好心人把题目的意思说清楚啊.求求你们了.
Top
回复人:lgxysl(我心欲静) ( 一级(初级)) 信誉:100 2005-7-6 19:33:42 得分:0
?


没看懂题.郁闷.理解能力弱.
楼长能不能把题说的清楚一些.求什么?
或者哪位读懂题目了能把题目贴一下好吗?
——————————————————————————
题目的意思就是
两个球队打了4场球,每场球有胜、平、负3种情况,最后各个球队的总比分有70分以下,70分,71分, ……,120分,120分以上这些情况,问这4场球打下来后,两个球队的胜负有多少种可能的组合情况。
提示:不同的胜平负情况和不同的总比分情况视为不同的情况。例如:两队4场都打平,则有:
(1111,1111;69以下:69以下)、(1111,1111,70:70)、(1111,1111,71:71)等不同的53种情况。
Top
回复人:cunsh(找工作) ( 一级(初级)) 信誉:100 2005-7-6 20:09:11 得分:0
?


谢谢你啊.我想想办法先.
Top
回复人:cunsh(找工作) ( 一级(初级)) 信誉:100 2005-7-6 20:10:14 得分:0
?


一边吃饭一边想.
Top
回复人:klosa(力力) ( 一级(初级)) 信誉:100 2005-7-6 21:17:31 得分:0
?


看不懂,友情帮顶了
Top
回复人:z19820201(waysun) ( 一级(初级)) 信誉:100 2005-7-6 21:28:12 得分:0
?


lgxysl(我心欲静)不错,我就不再跟进了,这个已经花了我不少时间了。各位大侠继续,直到出结果为止。我最终的结果为180089。
Top
回复人:CSDNWW(中国软件WW) ( 一级(初级)) 信誉:100 2005-7-6 22:20:36 得分:0
?


Eric的答案非常好!
>>/******总比分从70(70以下算做一种情况)到120(120以上算做一种情况)****/
>>两队都为“70”或“120”时,节得分情况有3的四次方种,此为特例,不要减去上述两种情况
>>所以
>>结果为:205479+2*2=205483
但上述说法要改为: 因为(70以下算做一种情况), (120以上算做一种情况)所以又多出2(A) * 2(B)4种, 结果为:205479+4=205483


Top
回复人:lgxysl(我心欲静) ( 一级(初级)) 信誉:100 2005-7-6 22:39:32 得分:0
?


我也不跟了。
楼主都不来,还跟什么。
反正算法就是那样,最后的得数已无关紧要了。
Top
回复人:yuanarea(超级赛亚人) ( 一级(初级)) 信誉:100 2005-7-6 23:41:12 得分:0
?


up
Top
回复人:cizhenxin() ( 一级(初级)) 信誉:100 2005-7-7 18:59:48 得分:0
?


高手!
看了大家的讨论才知道我的分析是很不全面的
UP先


Top
回复人:winzz123(忙啊盲) ( 一级(初级)) 信誉:100 2005-7-8 9:15:43 得分:0
?




先假设让A队胜
在比分上可以有1+2+..+52=1378种胜利方法
在节上,只要4节比赛中有一节是3,则整场比赛可能胜利。这样共81-16=65种
所以双方互有胜负的情况有1378*65*2=179140种
再加上平局还是跟答案不一样!哎!!!!!!!!!!!!!!!!!!!!!!!!







(1-15微软)

1.先作一个两分钟左右的自我介绍
例:
我说了:姓名,学校,专业,爱好,技能情况,获奖情况。


2.进程和线程的差别
例:
我对Windows NT基础掌握得不错,从线程,进程的定义,相互联系情况,线程,进程之间的通信,同步方法作了详细的介绍


3.heap/stack的差别
例:
这个问题我在论坛上跟朋友讨论过很多次了,我直接说出他们实质上的一致性和用法上的差别,然后具体到heap管理API,并且结合C/C++中的new/malloc进行了讨论。对方听见到我说到malloc,立刻就要我回答C/C++中heap的管理和系统API之间的关系。其实我要是不了解这两个的关系,我在前面是不会他们结合起来讨论的。我直接切如CRT进行讨论,对方比较满意,然后问了一些CRT的相关问题,比如CRT除了调用系统api,他自己要不要做一些工作等等。


4.关于COM的理解
例:
对于COM,我是理论大大多于实践,我对COM的知识完全来源于Essential COM。我讨论了COM的目的,C++的缺陷,COM为什么是better C++,COM的线程模型等等。我回答得有点乱,因为对方没有问COM具体某方面的东西,我就尽我所能,按照章节把essential COM里面的东西说了一遍,基本上抓住了要点。


5.Windows 下的内存是如何管理的
例:
我一时没反应过来,本来应该先说内核空间/用户空间
的区别,然后说进程空间,然后再深入。结果我直接就开始从分页机制开始说,我说每
个进程都有独立的32bits空间,寻址通过分页完成。分页其实不是Windows NT内核做的
,主要是IA32 chips做的。然后具体说了32bits地址如何映射成物理地址,GDT/LDT,导
致虚存转换的GP异常等等。


6.安全性
例:
我平时不太注意安全性,只是在看inside win
2k的时候了解了一部分。我说用户登录的时候会带一个token,通过token来对这个用户访问的object做限制,然后对方要我说windows privilige,我不清楚这个权限到底是什么,问他是不是要我说ring 0/ring 3的东西,对方说不是,那我也猜不出这个是要我说什么,我也就只有大概介绍进程独立阿,用户态不能访问内核态阿一些基本的东西,感觉对方不太满意。


7.介绍.net和.net的安全性
例:
天,我上个星期才开始了解.net,而后来才知道对方是ms GTEC .net方面最
牛的。还好我看的是bible: essential .net,我就大概背了一些书上的内容,bettercom ,具体的优越性是什么,是如何实现的。然后对方问我客户端如何访问.net组件实现web service,我心里在想,调用远程的.net 组件就可以了阿,不知道他要问我什么。于是只有说了说web service跟传统的application的差别。现在想起来对方可能是想问我xml/soap,可惜当时没想到。最后一个问题就是.net的安全性。My God!security是那本书里面的倒数第二,三章,我恰好看到倒数第四章。没办法,我只说了我了解的数字签名保证组件完整性,关键的domin我就没有说,只有承认自己还不太了解。当然,中间还插了一些小问题,比如是否了解Windows DNA阿,可惜我不太了解,只知道是个三层结
构.电话面试基本上就到此为止.


8.虚表是如何完成?
例:
其实这是一个小问题,但是VC里面对于虚表实现的细节非常的多,我也都有了解,所以我还不知道从何所起。整理一下思路后,我先说我是从inside the c++ object model入门的,然后谈了什么情况下有虚表,保存在什么地方,成员函数调用的时候如果访问到虚表,虚函数重写是如何实现的。


9.纯虚函数和虚函数的差别?
例:
我直接回答对方除了在语义层面上虚基类不能具现object外,再续表上没差别。


10.多重继承下的内存布局?
例:
于是我就分普通多重继承,虚多重继承讨论,说到这两种情况下如何修改虚表里面的内容,各个编译器在实现上哪些是一致的,那些是不同的。


11.讨论COM的线程模型
例:
这东西我当初了解得很清楚,不过很久没用,忘记不少,MTA这个名字我都忘记了,只有用中文给他说.我说道为什么会存在线程模型,为什么要列集,散列,进程内的STA通过hidden windows message queue实现安全性,本地通过LPC,远程通过PRC等等.把基本上的说清楚了,具体缓解比如代理,存根接口,我只说了通过MIDL会自动生成标准的.c 文件,更具体的由于我不太清楚,也就没有深入讨论了.


12.给两个变量,如何找出一个带环单链表中是什么地方出现环的?
例:
我看过expert C programmi
ng,里面最后有一个短文是介绍微软面试的,第一个题目就是如何判断链表出现了环,里面讨论了四种情况和各自的特点.虽然问题跟这里不同,但是既然我看到了,我就要突出自己一下,于是个他说了如何判定是否有环.他非常满意,但是申明他的问题是要找出环出现的节点,因为受到判定环算法的定向思维,我在一分钟内没有找出一个很好的答案,于是就问了一些"是否一定有环"这样的问题来拖了一下时间.后来我想到对方主要是考验我的思维能力而不是一定要解答出这个问题,我就说了一种不一定行得通的方案,做法就是先找到环内部的一个节点,遍历环一周,把访问到的节点地址相加,然后在第二周,把访问到的节点相减.因为出现环的节点会被多计算一次,所以最后得到的值就是出现环的地方.其实当时我就知道这个方法基本上行不通,但是对方还是对我这种做法感到非常满意,虚惊一场。


13.在IA32中一共有多少种办法从用户态跳到内核态?
例:
这方面的东西主要是IA32 vol3里面介绍的,我只记得Windows 跳入内核态的方法.于是我就开始说,说到一半,我突然想起以前讨论CIH病毒实现方法,就是通过任务门跳进去,想到这个,接下来的中断门,陷阱门也就想到了.好像对方对IA32比较有兴趣,问道我是如何用汇编做的Windows平台下的mp3播放器,于是我就说资料来源主要是网上的,同时用汇编编写win32程序其实跟用c语言调用sdk没什么差别,然后还老实承认mp3解码部分不是自己做得等等.


14.进程内/外组件的差别?
例:
我的回答跟一面的回答差不多


15.IUnknown接口?
例:
哇,他这不是放我发挥嘛.于是我针对这个接口的三个函数作了讨论,重点是 queryinterface,讨论了essential COM里面强调了三个特性,对方终于满意了.接下来的话题就很轻松了,问我看过哪些原版书,我问他那方面,他说不管什么方面,说出名字就可以.嘿嘿,偶的强项啊!从C++开
始说,五本宝典说完了就说windows SDK方面的aw/inside win2k,然后说调试方面的windows debugging,然后说TCP/IP方面的两本bible,我还准备说msj里面的under the hood和看过的ms无错编程这些更专业一点的东西,但是对方笑着把我打断,看来后面的不用说了.最后问我对.net知道多少,.net啊.net,我最不熟悉的东西.他让我介绍process/thread/domin/thread pool的差别,还好,我仔细看了domin,前面两个我本来就知道,thread pool我知道是什么东西,于是说就说了我自己知道的部分.说完了看得出来我也了解我.net的水平很有限,然后问我如果一个class里面只有一个private成员,客户怎么访问,我想了想,实在不知道,一点都不知道,就只有说不知道了,他笑着给我介绍了一下,然后再问了一个.net的名词解释,我还是不知道,他说没关系.总的来说挺不错,他让我等着,然后出去了.






(16-26 Moto笔试题)
16.打印如下图案,共19行,只能有一个for循环(题目已经提供)
         *         
        ***        
       *****       
      *******      
     *********     
    ***********
   *************   
  ***************  
 ***************** 
*******************
 ***************** 
  ***************  
   *************   
    ***********    
     *********     
      *******      
       *****       
        ***        
         *         
for(i=0;i<19;i++)
{


}




17.
void fun(int x)
{
if(x/2>0) fun(x/2);
printf("%d",x);
}
求fun(10)的输出结果.


(OK)答:12510


18.
#define f1(n) (n)*(n)


         int i=5;
int k=0;
k=f1(i++);
printf("%d %d",i,k);
输出结果:


(OK)答:7 25
只要记住(i++)+(i++)+(i++)=0和(++i)+(++i)+(++i)=7就好办了.




19。下面那个for循环是无限循环
for(int i=010;i==10;i+=0)


for(int i=10;(i++^--i)==0;i+=0)


(OK)答:第2个是死循环,因为i++的值永远不能和--i相等.




20.Email relay(传递) 和Email access分别用了什么协议?


(OK)答:SMTP POP




22.
int i;
int x=0x12345678;
unsigned char *p=(unsigned char *)&x;
for(i=0;i<sizeof(x);i++)
printf("%2x",*(p+i));


在80x86pc机器上运行结果
Sun Sparc Unix上运行结果
(OK)答:78563412 12345678


23.
char a[2][2][3]={{{1,6,3},{5,4,15}},{{3,5,33},{23,12,7}} };


for(int i=0;i<12;i++)
printf("%d ",_______);
空格处填上合适的语句,顺序打印出a中的数字


(OK)答: *(&a[0][0][0]+i)




24.
void fun(char *a,char *b)
{
a=b;
(*a)++;
}
void main()
{
char s1='A',s2='a';
char *p1=&s1;
char *p2=&s2;
fun(p1,p2);
printf("%c%c",s1,s2);
}
输出结果:
(OK)答:A b




25.写一个strstr()函数




26.
class human
{
public:
human(){ human_num++;};
static int human_num;
~human(){
human_num--;
print();
}
void print()
{
cout<<"human nun is: "<<human_num<<endl;
}
protected:
private:
};
int human::human_num = 0;


human f1(human x)
{
x.print();
return x;
}


int main(int argc, char* argv[])
{
human h1;
h1.print();
human h2  = f1(h1);
h2.print();


return 0;
}
写出程序的输出结果:


(OK)答:
human nun is:1
human nun is:1
human nun is:0
human nun is:0
human nun is:-1
human nun is:-2


通过这个题受到一点启发,不管什么样的题都不能想当然,一切要有根据。还有一点就是,不管是在内存还是在压栈或者返回值中,构造函数和析构函数的规则都是一样的。在这个题中,因为返回值由h2来接收,所以不会将返回值x放到寄存器中了,而是直接由x构造h2. 






1.有一个从小到大排列的数组,里面可能有相同的数字,请找出最长的连字长度,如:
  1,2,3,3,3,3,5,6,6,6  最长的长度为4
int GetLongLength(int a[],int n)  
{  int length=1;
   for(int i=1;i<=n;i++)
   {
      if(      ?      ) 
        length++;
   }
   return length;
}
在空格里填写条件,该函数返回数组里的最长连子长度


2.对于27有:13+14=27;2+3+4+5+6+7=27;8+9+10=27等,请找出相加等于10000的所有正整数的组合。提示;设一个组合里的最小值为left,最大值为right,找出所有附合条件的(left,right)对(题目里的提示).






1.两个数相乘,小数点后位数没有限制,请写一个高精度算法


2.字符串排序


3.二分法搜索


4.如何调用地址为0的函数,写出代码.(VIA笔试题)
(OK)答:
0就是NULL,可以是任意类型指针的取值。所以你将0强制转化为一个函数指针就可以了。
i.e.
typedef void (*pFunc)(void);


((pFunc)0)();








软件笔试题
1. How do you code an infinite loop in C?


2. Volatile:
  (1)What does the keyword volatile mean? Give an example
  (2)Can a parameter be both const and volatile? Give an example
  (3)Can a pointer be volatile? Give an example


3. What are the values of a, b, and c after the following instructions:
  int a=5, b=7, c;
  c = a+++b;
(OK)答:
优先组成最长的操作符,相当于c = (a++) + b;
所以结果为12


4. What do the following declarations mean?
  (1)const int a;
  (2)int const a;
  (3)const int *a;
  (4)int * const a;
  (5)int const * a const;


5. Which of the following statements describe the use of the keyword static?
  (1)Within the body of a function: A static variable maintains its value between function revocations
  (2)Within a module: A static variable is accessible by all functions within that module
  (3)Within a module: A static function can only be called by other functions within that module


6. Embedded systems always require the user to manipulate bits in registers or variables. Given an integer variable a, write two code fragments.
  The first should set bit 5 of a. The second shnuld clear bit 5 of a. In both cases, the remaining bits should be unmodified.


7. What does the following function return?
  char foo(void)
  {
   unsigned int a = 6;
   int b = -20;
   char c;
   (a+b > 6) ? (c=1): (c=0);
   return c;
  }
(OK)答:
这涉及不同类型的值进行转换的问题,一般转换的规则是短的向长的,修饰短的向修饰长的,一般的向特殊的转化。
在这儿,因为a和b类型不一样,所以有符号的会转换为无符号的,所以a+b肯定是正的,故a+b > 6为真
所以,不同类型不同长度值之间的转换一定要谨慎!
短向长转换以最高位进行填充,长向短转换直接截断
例:
int a = (char)0x80;       // a = 0xFFFFFF80
char b  = 0x00000100;     // b = 0x00


8. What will be the output of the following C code?
  main()
  {
   int k, num= 30;
   k =(num > 5 ? (num <=10 ? 100:200): 500);
   printf(“%d”, k);
  }
(OK)答: 200
没有什么考的


9. What will the following C code do?
int *ptr;
ptr =(int *)0x67a9;
*ptr = 0xaa55;
(OK)答: 将从0x67a9地址开始的4个字节内存看作是一个int,然后将0xaa55赋值给这个int
一般情况下程序都应该挂掉!


10. What will be the output of the follow C code?
  #define product(x) (x*x)
  main()
  {
   int i = 3, j, k;
   j = product(i++);
   k = product(++i);
   printf(“%d %d”,j,k);
  }
(OK)答: 9 49


11. Simplify the following Boolean expression
  !((i ==12) || (j > 15))


(OK)答: i != 12 && j <= 15


12. How many flip-flop circuits are needed to divide by 16?


13. Provides 3 properties that make an OS, a RTOS?


14. What is pre-emption?


15. Assume the BC register value is 8538H, and the DE register value is 62A5H.Find the value of register BC after the following assembly operations:
  MOV A,C
  SUB E
  MOV C,A
  MOV A,B
  SBB D
  MOV B,A


16. In the Assembly code shown below
  LOOP: MVI C,78H
   DCR C
   JNZ LOOP
   HLT
  How many times is the DCR C Operation executed?


17. Describe the most efficient way (in term of execution time and code size) to divide a number by 4 in assembly language


18. what value is stored in m in the following assembly language code fragment if n=7?
   LDAA #n
  LABEL1: CMPA #5
   BHI L3
   BEQ L2
   DECA
   BRA L1
  LABEL2: CLRA
  LABEL3: STAA #m


19. What is the state of a process if a resource is not available?
  #define a 365*24*60*60


20. Using the #define statement, how would you declare a manifest constant that returns the number of seconds in a year? Disregard leap years in your answer.


21. Interrupts are an important part of embedded systems. Consequently, many compiler vendors offer an extension to standard C to support interrupts. Typically, the keyword is __interrupt. The following routine (ISR). Point out problems in the code.
  __interrupt double compute_area (double radius)
  {
   double area = PI * radius * radius;
   printf(“\nArea = %f”, area);
   return area;
  }






联想笔试题
1.设计函数 int atoi(char *s)。


2.int i=(j=4,k=8,l=16,m=32); printf(“%d”, i); 输出是多少?


3.解释局部变量、全局变量和静态变量的含义。


4.解释堆和栈的区别。


5.论述含参数的宏与函数的优缺点。




普天C++笔试题
1.实现双向链表删除一个节点P,在节点P后插入一个节点,写出这两个函数。


2.写一个函数,将其中的\t都转换成4个空格。


3.Windows程序的入口是哪里?写出Windows消息机制的流程。


4.如何定义和实现一个类的成员函数为回调函数?


5.C++里面是不是所有的动作都是main()引起的?如果不是,请举例。


6.C++里面如何声明const void f(void)函数为C程序中的库函数?


7.下列哪两个是等同的
  int b;
  A const int* a = &b;
  B const* int a = &b;
  C const int* const a = &b;
  D int const* const a = &b;
(OK)答: CD
对于B,在VC6.0中出现警告:
warning C4518: 'int ' : storage-class or type specifier(s) unexpected here; ignored
所以B相当于const* /*int*/ c = &b;


8.内联函数在编译时是否做参数类型检查?
  void g(base & b){
   b.play;
  }
  void main(){
   son s;
   g(s);
   return;
  }




华为笔试题
1.请你分别画出OSI的七层网络结构图和TCP/IP的五层结构图。


2.请你详细地解释一下IP协议的定义,在哪个层上面?主要有什么作用?TCP与UDP呢?


3.请问交换机和路由器各自的实现原理是什么?分别在哪个层次上面实现的?


4.请问C++的类和C里面的struct有什么区别?


5.请讲一讲析构函数和虚函数的用法和作用。


6.全局变量和局部变量有什么区别?是怎么实现的?操作系统和编译器是怎么知道的?


7.8086是多少位的系统?在数据总线上是怎么实现的?








Sony笔试题
1.完成下列程序
  *
  *.*.
  *..*..*..
  *...*...*...*...
  *....*....*....*....*....
  *.....*.....*.....*.....*.....*.....
  *......*......*......*......*......*......*......
  *.......*.......*.......*.......*.......*.......*.......*.......
  #include <stdio.h>
  #define N 8
  int main()
  {
   int i;
   int j;
   int k;
   ---------------------------------------------------------
   | |
   | |
   | |
   ---------------------------------------------------------
   return 0;
  }




2.完成程序,实现对数组的降序排序
  #include <stdio.h>
  void sort( );
  int main()
  {
   int array[]={45,56,76,234,1,34,23,2,3}; //数字任//意给出
   sort( );
   return 0;
  }
  void sort( )
  {
   ____________________________________
   | |
   | |
   |-----------------------------------------------------|
  }


3.费波那其数列,1,1,2,3,5……编写程序求第十项。可以用递归,也可以用其他方法,但要说明你选择的理由。
  #include <stdio.h>
  int Pheponatch(int);
  int main()
  {
   printf("The 10th is %d",Pheponatch(10));
   return 0;
  }
  int Pheponatch(int N)
  {
  --------------------------------
  | |
  | |
  --------------------------------
  }


4.下列程序运行时会崩溃,请找出错误并改正,并且说明原因。
  #include <stdio.h>
  #include <malloc.h>
  typedef struct{
   TNode* left;
   TNode* right;
   int value;
  } TNode;
  TNode* root=NULL;
  void append(int N);
  int main()
  {
   append(63);
   append(45);
   append(32);
   append(77);
   append(96);
   append(21);
   append(17); // Again, 数字任意给出
  }
  void append(int N)
  {
   TNode* NewNode=(TNode *)malloc(sizeof(TNode));
   NewNode->value=N;
  
   if(root==NULL)
   {
   root=NewNode;
   return;
   }
   else
   {
   TNode* temp;
   temp=root;
   while((N>=temp.value && temp.left!=NULL) || (N<temp. value && temp. right!=NULL
  ))
   {
   while(N>=temp.value && temp.left!=NULL)
   temp=temp.left;
   while(N<temp.value && temp.right!=NULL)
   temp=temp.right;
   }
   if(N>=temp.value)
   temp.left=NewNode;
   else
   temp.right=NewNode;
   return;
   }
  }








1.写出下列算法的时间复杂度。
(1)冒泡排序;
(2)选择排序;
(3)插入排序;
(4)快速排序;
(5)堆排序;
(6)归并排序;


2.写出下列程序在X86上的运行结果。


struct mybitfields
{
unsigned short a : 4;
unsigned short b : 5;
unsigned short c : 7;
}test


void main(void)
{
int i;
test.a=2;
test.b=3;
test.c=0;


i=*((short *)&test);
printf("%d\n",i);
}


3.写出下列程序的运行结果。
void main()
{
unsigned int i=3;
cout<<i * -1;
cout.flush();

system("pause");
}
(OK)答: 4294967293(即0xfffffffd)
实际上就是打印-3, cout<<i * -1;执行之后可能不能立即看到输出,调用flush是必要的。


4.写出下列程序所有可能的运行结果。


int a;
int b;
int c;


void F1()
{
b=a*2;
a=b;
}


void F2()
{
c=a+1;
a=c;
}


main()
{
a=5;
//Start F1,F2 in parallel
F1(); F2();
printf("a=%d\n",a);
}


5.CharPrev()函数的作用。


6.对 16 Bits colors的处理,要求:
(1)Byte转换为RGB时,保留高5、6bits;
(2)RGB转换为Byte时,第2、3位置零。




7.一个链表的操作,注意代码的健壮和安全性。要求:
(1)增加一个元素;
(2)获得头元素;
(3)弹出头元素(获得值并删除)




8.一个给定的数值由左边开始升位到右边第N位,如
0010<<1 == 0100
或者
0001 0011<<4 == 0011 0000
请用C或者C++或者其他X86上能运行的程序实现。




附加题(只有在完成以上题目后,才获准回答)
In C++, what does "explicit" mean? what does "protected" mean?


(OK)答:
例1:
class Test
{
public:
explicit Test(int i){}
};


void fun(Test t)
{


}


void main()
{
fun(3);   // error C2664.去掉explicit就可以。


system("pause");
}
explicit意味着not be considered for implicit conversions.即不能将3隐式转换为类CTest,只能显式生成对象: CTest t(3);


protected意味着只有本类成员函数和其子类成员函数才能访问protected成员。




华为面试题


1.请问(1),(2)中Test函数输出结果分别是什么?
(1) void GetMemory(char *p)
  {
  p = (char *)malloc(100);
  }
  void Test(void)
  {
  char *str = NULL;
  GetMemory(str);
  strcpy(str, "hello world");
  printf(str);
  }
(OK)答: 程序挂掉,不能往NULL地址拷贝字符串


 (2) void GetMemory2(char **p, int num)
  {
  *p = (char *)malloc(num);
  }
  void Test(void)
  {
  char *str = NULL;
  GetMemory(&str, 100);
  strcpy(str, "hello");
  printf(str);
  }
(OK)答: hello


2.找错题


void test1()
{
    char string[10];
    char* str1=”0123456789”;
strcpy(string, str1);
}
(OK)答: 数组越界


void test2()
{
    char string[10], str1[10];
for(I=0; I<10;I++)
{
        str1[i] =’a’;
}
strcpy(string, str1);
}
(OK)答: str1是一个末尾元素不是0的字符数组,不能把它当作字符串使用,否则程序不可预料


void test3(char* str1)
{
    char string[10];
    if(strlen(str1)<=10)
{
    strcpy(string, str1);
}
}
(OK)答: str1长度等于10时数组string会越界






3.写出程序运行结果


int sum(int a)
{
        auto int c=0;
        static int b=3;
c+=1;
b+=2;
return(a+b+C);
}
    
void main()
{
        int I;
int a=2;
for(I=0;I<5;I++)
{
    printf(“%d,”, sum(a));
}
}


(OK)答: 8,10,12,14,16


4.    
int func(int a)
{
    int b;
    switch(a)
    {
        case 1: 30;
        case 2: 20;
        case 3: 16;
        default: 0
}
return b;
}
则func(1)=?


(OK)答: b未被初始化,返回值不可预料


5.
int a[3];
a[0]=0; a[1]=1; a[2]=2;
int *p, *q;
p=a;
q=&a[2];
则a[q-p]=?


(OK)答: 2


6. 
定义 int **a[3][4], 则变量占有的内存空间为:_____
(OK)答: 48
3*4*sizeof(int**) = 48


7.
编写一个函数,要求输入年月日时分秒,输出该年月日时分秒的下一秒。如输入2004年12月31日23时59分59秒,则输出2005年1月1日0时0分0秒。




8.设计函数 int atoi(char *s)


9. What do the following declarations mean?
  (1)const int a;
  (2)int const a;
  (3)const int *a;
  (4)int * const a;
  (5)int const * a const;


10.编程
  将整数转换成字符串:void itoa(int,char);
  例如itoa(-123,s[])则s=“-123”;


11.10个人分成4组 有几种分法?(程序)(不能重复,如:1,1,1,7=7,1,1,1)


12.如图: 
     7 8 9 10
     6 1 2 11
     5 4 3 12
    16 15 14 13
    设“1”的坐标为(0,0) “7”的坐标为(-1,-1) 编写一个小程序,使程序做到输入坐标(X,Y)之后显示出相应的数字。


13.编最优化Bubble(int *pIntArray,int L),要求:交换元素不能用临时变量,如果有序需要最优。




14.不运行程序写出该程序的运行结果?
#include "iostream.h"
class B
{
public:
B()
{
cout<<"default constructor"<<endl;
}
~B()
{
cout<<"destructed"<<endl;
}
B(int i):data(i)
{
cout<<"constructed by parameter " << data <<endl;
}
private:
int data;
};
B Play( B b)
{
return b ;
}
int main(int argc, char* argv[])
{
B temp = Play(5);
return 0;
}


运行结果:
constructed by parameter 5
destructed
destructed


注释:上面这个题主要涉及自动类型转换。
     见<<Thinking in C++>>中296页。在C和C++中,如果编译器看到一个表达式或函数使用了一个不适合的内部类型,他经常会执行一个自动类型转换,从现在的类型到所要求的类型。在C++中,可以通过定义自动类型转换函数来为用户定义类型达到相同效果。这些函数有两种类型:特殊类型的构造函数和重载的运算符。在上例中,Play需要一个B类型的参数,但是我们传入的实参类型是int,此时,编译器会查看是否有适当的自动类型转换函数将int转变为B.显然,通过构造函数B(int i)可以实现。当Play返回之后,产生了一个临时B对象,然后编译器调用拷贝构造函数用临时对象初始化temp.因为我们没有定义拷贝构造函数,所以编译器默认产生一个拷贝构造函数,它的功能仅仅是进行位拷贝而已。这一条语句执行完,临时对象被销毁,调用析构函数。当出了main函数后,temp调用析构函数。:)




最经典面试题:
1)sizeof相关系列问题


2)const相关系列问题


3)大量林锐书的习题,以及各种变种




1)求出相似度的算法.


2)写出二分查找的代码.


3)写出在母串中查找子串出现次数的代码.


4)写出快速排序或者某种排序算法代码


5)写出查找从一个集合中输出所有子集合的算法.


6)实现strcpy函数




7)实现strcmp函数




8)将一个单链表逆序


9)循环链表的节点对换和删除。


10)将一个数字字符串转换为数字."1234" -->1234


11)实现任意长度的整数相加或者相乘功能。


12)写函数完成内存的拷贝






synopsys笔试题 
1.给出指针的数据类型


   a,float (**p)[10]
   b, double *(*p)[10]
   c, 记不清了,大概是 char *(*p)()之类的
   d, int  *((*p)[10])


2.给出进程间通信的方法


3.给出程序执行结果
 a void func(char **p, int num)
   {
        *p = malloc(num);
    }


    main()
   {
       char *p=NULL;
       func(&p, 100);


       strcpy(p,"blabla");
       printf("%s",p);


       free(p);
    }


 b  main()    
   {
       char *p=NULL;
       p = malloc(100);
       strcpy(p,"blabla");
       free(p);


       printf("%s",p);
    }




4. a,一个正整数序列,值最大不超过K,没有重复项,给出排序算法
   b,如果有重复项,需要对排序算法做何改动
   c,证明算法最坏情况下复杂度为O(N)
   d,给出算法的空间复杂度


5. 给出二叉树中序遍历算法,包括数据结构和函数实现


6. 设计一个model,满足下列条件
   a,分为test group 和develop group两部分
   b,develop group是test group的3倍
   c,要求能够并行处理,比如develop 2nd的时候,可以test 1st
   d,任何形式的设计都可以


7. 描述多线程程序的并行处理


8. dy/dx=y  y(0)=1 求 x=0.4
   a h=0.2 h=0.1 分别计算y(0.4)
   b 根据误差和h成正比的公式,计算出h=0时的y(0.4)
   c 要达到和b同等精度,需要迭代计算多少次(?)


9 比较两套程序写法哪个好,为什么
  a
  (1)   for(i=1;i<k;i++)
       {
           a = i + b + c * j;
           printf("%d",a);
        }


  (2)  a = b + c * j;
       for(i=1;i<k;i++)
      {
          printf("%d",a+i);
       }
   
  b   char a
  (1)   if(a=='A') ....
        
  (2)   if('A'==a) ....


10.给出表达式的树结构表示 black=red+green×7+blue








今天遇到的面试题目




1.有以下表达式:
int a=248; b=4;int const c=21;const int *d=&a;
int *const e=&b;int const *f const =&a;
请问下列表达式哪些会被编译器禁止?为什么?
*c=32;d=&b;*d=43;e=34;e=&a;f=0x321f;


2.交换两个变量的值,不使用第三个变量。即a=3,b=5,交换之后a=5,b=3;




3.c和c++中的struct有什么不同?




4.#include <stdio.h>
#include <stdlib.h>
void getmemory(char *p)
{
p=(char *) malloc(100);
strcpy(p,"hello world")
}
int main( )
{
char *str=NULL;
getmemory(str);
print("%s/n",str);
free(str);
return 0;
}
程序运行的结果是什么?为什么?


5.char szstr[10];
strcpy(szstr,"0123456789");
产生什么结果?为什么?




6.列举几种进程的同步机制,并比较其优缺点。




7.进程之间数据交换的途径




8.类的静态成员和非静态成员有何区别?




9.纯虚函数如何定义?使用时应注意什么?




10.数组和链表的区别




11.写一个函数比较两个字符串str1和str2的大小,若相等返回0,若str1大于
str2返回1,若str1小于str2返回-1




12.ISO的七层模型是什么?TCP/UDP是属于哪一层?TCP/UDP有何优缺点?








面试常考问题


1、文档在开发中的作用及重要性




2、数据结构问题:树、二叉树、链表、队列、堆栈




3、数据库基本知识:B_Tree、R_Tree等




4、程序、进程和线程的概念和关系


(1)进程是加载到内存中的程序,以及分配给这个程序的所有资源。


(2)当你运行一个程序,你就启动了一个进程。显然,程序是死的(静态的),进程是活的(动态的)。进程可以分为系统进程和用户进程。凡是用于完成操作系统的各种功能的进程就是系统进程,它们就是处于运行状态下的操作系统本身;用户进程就是所有由你启动的进程。


(3)线程是程序的一次执行中执行的一段程序片段,是处理机的最小调度单位。


(4)每个进程都拥有一个初始线程(即主线程),初始线程可以有选择的创建其他线程。


(4)注意,进程是最小的资源分配单位,线程是最小的调度单位。属于一个进程的所有线程都共享这个进程的资源。进程是房子,而线程居住其中。


5.怎样使程序易于维护




6.指针和引用


(1)int x = 20;


    Int* ptrx = &x; //声明指针,并赋值


    Int z = *ptrx;//重引用指针(dereferencing pointer)


注:ptrx——x的内存地址


    *ptrx——ptrx所指向的对象的值,即x的值


(2)引用(Reference)


MyStruct* pStruct = new MyStruct;


    MyStruct& Ref = *pStruct;


    Ref.x = 100;


等同于


MyStruct& Ref = * new MyStruct;


    Ref.x = 100;


(3)引用与指针的区别:


指针可以先声明再赋值;


而引用不可以,它必须在声明时就进行初始化。



  • 0
    点赞
  • 0
    评论
  • 4
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值