<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Статьи о программировании, все о программировании, исходники программ &#187; C/C++/C#</title>
	<atom:link href="http://statprog.ru/category/ccc/feed/" rel="self" type="application/rss+xml" />
	<link>http://statprog.ru</link>
	<description>Авторские статьи, исходники, программы.</description>
	<lastBuildDate>Thu, 12 Aug 2010 16:53:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Определить попадание точки в прямоугольник или эллипс на C#</title>
		<link>http://statprog.ru/2010/05/29/opredelit-popadanie-tochki-v-pryamougolnik-ili-ellips-na-c/</link>
		<comments>http://statprog.ru/2010/05/29/opredelit-popadanie-tochki-v-pryamougolnik-ili-ellips-na-c/#comments</comments>
		<pubDate>Sat, 29 May 2010 18:44:56 +0000</pubDate>
		<dc:creator>evteev</dc:creator>
				<category><![CDATA[C/C++/C#]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[прямоугольник]]></category>
		<category><![CDATA[эллипс]]></category>

		<guid isPermaLink="false">http://statprog.ru/?p=453</guid>
		<description><![CDATA[Работая в Visual Studio в C# можно легко определить попала ли точка с координатами (X, Y) в область прямоугольника или эллипса. Определяется это даже без применения каких либо геометрических формул, все очень просто &#8211; с помощью стандартных средств Visual Studio. &#8230; <a href="http://statprog.ru/2010/05/29/opredelit-popadanie-tochki-v-pryamougolnik-ili-ellips-na-c/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Работая в Visual Studio в C# можно легко определить попала ли точка с координатами (X, Y) в область прямоугольника или эллипса. Определяется это даже без применения каких либо геометрических формул, все очень просто &#8211; с помощью стандартных средств Visual Studio.<span id="more-453"></span></p>
<p>Давайте посмотрим как же будем это определять.</p>
<pre class="brush: csharp;">//Сначала определим переменные с шириной и высотой прямоугольника и эллипса.
int RectangleWidth = 400;
int RectangleHeight = 200;
int EllipseWidth = 500;
int EllipseHeight = 450;

//Далее зададим им координаты размещения на форме.
int coordR_X = 200;
int coordR_Y = 200;
int coordE_X = 100;
int coordE_Y = 400;

//Создадим прямоугольник и эллипс.
Rectangle RectangleDraw = new Rectangle(coordR_X, coordR_Y, RectangleWidth, RectangleHeight);
Rectangle EllipseDraw = new Rectangle(coordE_X, coordE_Y, EllipseWidth, EllipseHeight);

//Создадим графическую область для прямоугольника и эллипса.
GraphicsPath GraphicsPathRectangle = new GraphicsPath();
GraphicsPath GraphicsPathEllipse = new GraphicsPath();

//Добавим в первую область созданный прямоугольник.
GraphicsPathRectangle.AddRectangle(RectangleDraw);

//Добавим во вторую область созданный эллипс.
GraphicsPathEllipse.AddEllipse(EllipseDraw);

//Создадим точку с координатами (100; 200).
Point PointUser = new Point(100, 200);</pre>
<p>Все, мы выполнили создание прямоугольника, эллипса и точки.<br />
Теперь давай проверим определим в какую область попала точка.<br />
С помощью объекта IsVisible можно это сделать.</p>
<pre class="brush: csharp;">
if (GraphicsPathEllipse.IsVisible(PointUser))
	MessageBox.Show(&quot;Попала в эллипс!&quot;);

if (GraphicsPathRectangle.IsVisible(PointUser))
	MessageBox.Show(&quot;Попала в прямоугольник!&quot;);
</pre>
]]></content:encoded>
			<wfw:commentRss>http://statprog.ru/2010/05/29/opredelit-popadanie-tochki-v-pryamougolnik-ili-ellips-na-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Пьяньчуга &#8211; Моделирование движения пьяного человека на C#</title>
		<link>http://statprog.ru/2010/01/28/pyanchuga-modelirovanie-dvizheniya-pyanogo-cheloveka-na-c/</link>
		<comments>http://statprog.ru/2010/01/28/pyanchuga-modelirovanie-dvizheniya-pyanogo-cheloveka-na-c/#comments</comments>
		<pubDate>Thu, 28 Jan 2010 14:59:09 +0000</pubDate>
		<dc:creator>evteev</dc:creator>
				<category><![CDATA[C/C++/C#]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[Моделирование]]></category>

		<guid isPermaLink="false">http://statprog.ru/?p=402</guid>
		<description><![CDATA[Надоели скучные и однообразные программы? Давайте немного пофантазируем и напишем программу, которая будет моделировать движение пьяного человека, и представим все это графически. Суть программы будет заключаться в следующем: Будем моделировать движение пьяного человека (он пьян до того, что не знает &#8230; <a href="http://statprog.ru/2010/01/28/pyanchuga-modelirovanie-dvizheniya-pyanogo-cheloveka-na-c/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Надоели скучные и однообразные программы? Давайте немного пофантазируем и напишем программу, которая будет моделировать движение пьяного человека, и представим все это графически.</p>
<p>Суть программы будет заключаться в следующем:</p>
<p>Будем моделировать движение пьяного человека (он пьян до того, что не знает что делает, но лежать ему не хочется). В начальный момент времени задается положение человека в некотором дворе с непроницаемыми стенками и одним выходом. Кроме того даются 5 вероятностей &#8211; остаться на месте и перемещаться в 4 стороны. Если появляется попытка переместиться через стенку, то «пьяньчуга» остается на месте. Сумма вероятностей строго равно 1. Если «пьяньчуга» нашел выход или попал в один из люков, то моделирование заканчивается и выводится соответствующее сообщение.<span id="more-402"></span></p>
<p>И так, в <strong>Visual Studio</strong> в <strong>C#</strong> создайте форму, и объекты как показано на рисунке «Рисунок 1.1». Соответственно, к каждому объекту подписано его имя.</p>
<p style="text-align: justify;"><img src="http://statprog.ru/wp-content/012810_1459_2.jpg" alt="Моделирование движения пьяного человека на C#" width="556" height="351" /></p>
<p style="text-align: justify;"><img src="http://statprog.ru/wp-content/012810_1459_1.png" alt="Рисунок 1.1" /></p>
<p style="text-align: justify;">
<p>После создания формы и всех ее объектов приступим к написанию кода программы.<br />
Для начала я перечислю, какие библиотеки и глобальные переменные необходимы для работы программы.<br />
<strong>Библиотеки:</strong></p>
<pre class="brush: csharp;">using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;</pre>
<p><strong>Глобальные переменные:</strong></p>
<pre class="brush: csharp;">Point[,] coord = new Point[11, 11];
Point[] coord_courses;
coord_points[] mass_points;
Point PointUser = new Point();
Point PointUser_For_searche = new Point();
int shag = 5;
Graphics Line;
Rectangle EllipseDraw = new Rectangle();
Rectangle EllipseDraw2 = new Rectangle();
GraphicsPath GraphicsPathEllipse;</pre>
<p>Для того чтобы запоминать сколько раз «пьяньчуга» попадал в ту или иную точку, мы будем использовать структуру «coord_points», которая включает в себя координаты точки x и y и количество попаданий «Count». Структуру объявляем глобально.</p>
<pre class="brush: csharp;">public struct coord_points
{
	int x;
	int y;
	int Count;
	public coord_points(int X, int Y, int count)
	{
		x = X;
		y = Y;
		Count = count;
	}
	public int X
	{
		get { return x; }
		set { x = value; }
	}
	public int Y
	{
		get { return y; }
		set { y = value; }
	}
	public int count
	{
		get { return Count; }
		set { Count = value; }
	}
};</pre>
<p>Теперь напишем код для кнопки «Нарисовать местность».</p>
<pre class="brush: csharp;">	pictureBox.Refresh(); //Обновить область для рисования
	listBox1.Items.Clear(); // Очищаем ListBox с координатами
	isleovanie.Text = &quot;&quot;; // Очищаем значение исследования
	Line = Graphics.FromHwnd(pictureBox.Handle); // Создаем объект для рисования на pictureBox

	count_iter.Text = 0.ToString();//Обнуляем поле «Кол-во итераций»
	distance.Text = 0.ToString();//Обнуляем поле «Расстояние (пиксеметры)»

	count_courses.Text = 0.ToString();//Обнуляем поле «Общее кол-во шагов»
	count_down.Text = 0.ToString();//Обнуляем поле количество шагов «Вниз»
	count_up.Text = 0.ToString();//Обнуляем поле количество шагов «Вверх»
	count_l.Text = 0.ToString();//Обнуляем поле количество шагов «Влево»
	count_r.Text = 0.ToString();//Обнуляем поле количество шагов «Вправо»

	System.Drawing.Pen red = new Pen(Color.Red, 1);
	SolidBrush EllipseBrush = new SolidBrush(Color.Black);
	Graphics Ellipse = Graphics.FromHwnd(pictureBox.Handle);
	Graphics Ellipse2 = Graphics.FromHwnd(pictureBox.Handle);
	GraphicsPathEllipse = new GraphicsPath();
	Random rnd = new Random();
	int max_h = pictureBox.Height / 2 + pictureBox.Height / 4;
	int max_w = pictureBox.Width / 2 + pictureBox.Width / 4;
	int temp = 0;

	Point start1 = new Point(10, 10);
	Point start2 = new Point(10, 10);
	Point end1 = new Point(10, pictureBox.Height - 50);
	Point end2 = new Point(pictureBox.Width - 10, 10);
	Point end3 = new Point(pictureBox.Width - 10, pictureBox.Height - 50);
	//Координаты помещения
	coord[0, 0].X = end2.X - rnd.Next(pictureBox.Width / 3, pictureBox.Width / 2);
	coord[0, 0].Y = start1.Y;
	coord[0, 1].X = end2.X - rnd.Next(5, pictureBox.Width / 3);
	coord[0, 1].Y = end2.Y;
	//Слева линия
	coord[1, 0].X = start1.X;
	coord[1, 0].Y = start1.Y;
	coord[1, 1].X = end1.X;
	coord[1, 1].Y = end1.Y;
	//Верхняя
	coord[2, 0].X = start1.X;
	coord[2, 0].Y = start1.Y;
	coord[2, 1].X = coord[0, 0].X;
	coord[2, 1].Y = end2.Y;
	//Верхняя 2
	coord[6, 0].X = coord[0, 1].X;
	coord[6, 0].Y = start1.Y;
	coord[6, 1].X = end2.X;
	coord[6, 1].Y = end2.Y;
	//Правая
	coord[3, 0].X = end2.X;
	coord[3, 0].Y = end2.Y;
	coord[3, 1].X = end3.X;
	coord[3, 1].Y = end3.Y;
	//Нижняя
	coord[4, 0].X = end1.X;
	coord[4, 0].Y = end1.Y;
	coord[4, 1].X = end3.X - pictureBox.Width / 2 - pictureBox.Width / 3 - rnd.Next(0, 30);
	coord[4, 1].Y = end3.Y;
	//Нижняя
	coord[7, 0].X = end3.X - pictureBox.Width / 4 - pictureBox.Width / 2 - rnd.Next(0, 50);
	coord[7, 0].Y = end1.Y;
	coord[7, 1].X = end3.X;
	coord[7, 1].Y = end3.Y;
	//Нижняя 2
	coord[8, 0].X = coord[4, 1].X;
	coord[8, 0].Y = end3.Y;
	coord[8, 1].X = coord[4, 1].X;
	coord[8, 1].Y = end3.Y + 40;
	//Нижняя 2
	coord[9, 0].X = coord[7, 0].X;
	coord[9, 0].Y = end3.Y;
	coord[9, 1].X = coord[7, 0].X;
	coord[9, 1].Y = coord[8, 1].Y;
	//Нижняя 3
	coord[10, 0].X = coord[8, 1].X;
	coord[10, 0].Y = coord[8, 1].Y;
	coord[10, 1].X = coord[9, 1].X;
	coord[10, 1].Y = coord[9, 1].Y;
	//Координаты для эллипса
	coord[5, 0].X = rnd.Next(50, max_w);
	coord[5, 0].Y = rnd.Next(50, max_h);
	coord[5, 1].X = rnd.Next(50, max_w);
	coord[5, 1].Y = rnd.Next(50, max_h);
	for (; ; )
	{
		if (coord[5, 1].X == 0 || coord[5, 1].Y == 0)
		{
			temp = rnd.Next(50, max_w);
			if (temp != coord[5, 0].X)
				coord[5, 1].X = temp;

			temp = rnd.Next(50, max_w);
			if (temp != coord[5, 0].Y)
				coord[5, 1].Y = temp;
		}
		else
			break;
	}
	//////////////////
	EllipseDraw = new Rectangle(coord[5, 0].X, coord[5, 0].Y, 10, 10);
	EllipseDraw2 = new Rectangle(coord[5, 1].X, coord[5, 1].Y, 10, 10);

	Line.DrawLine(red, start1.X, start1.Y, end1.X, end1.Y); //Левая

	Line.DrawLine(red, coord[2, 0].X, coord[2, 0].Y, coord[2, 1].X, coord[2, 1].Y); //Верхняя
	Line.DrawLine(red, coord[6, 0].X, coord[6, 0].Y, coord[6, 1].X, coord[6, 1].Y); //Верхняя

	Line.DrawLine(red, end2, end3); //Правая

	Line.DrawLine(red, coord[4, 0].X, coord[4, 0].Y, coord[4, 1].X, coord[4, 1].Y); //Нижняя прямая
	Line.DrawLine(red, coord[7, 0].X, coord[7, 0].Y, coord[7, 1].X, coord[7, 1].Y); //Нижняя прямая

	Line.DrawLine(red, coord[8, 0].X, coord[8, 0].Y, coord[8, 1].X, coord[8, 1].Y); //Нижняя 2 слева

	Line.DrawLine(red, coord[9, 0].X, coord[9, 0].Y, coord[9, 1].X, coord[9, 1].Y); //Нижняя 2 справа

	Line.DrawLine(red, coord[10, 0].X, coord[10, 0].Y, coord[10, 1].X, coord[10, 1].Y); //Нижняя 3 прямая

	int el_x1 = rnd.Next(50, max_w);
	int el_y1 = rnd.Next(50, max_h);

	GraphicsPathEllipse.AddEllipse(new Rectangle(el_x1, el_y1, 10, 10));//Рисуем первый люк
	Ellipse.FillEllipse(EllipseBrush, new Rectangle(el_x1, el_y1, 10, 10));
	//Рисуем случайно все остальные люки (kolvolukov.Text – кол-во люков)
	for (int i = 2; i &lt; = Convert.ToInt32(kolvolukov.Text); i++)
	{
		int el_x2 = rnd.Next(50, max_w);
		int el_y2 = rnd.Next(50, max_h);
		for (; ; )
		{
			if (el_x2 == 0 || el_y2 == 0)
			{
				temp = rnd.Next(50, max_w);
				if (temp != el_x1)
					el_x2 = temp;

				temp = rnd.Next(50, max_w);
				if (temp != el_y1)
					el_y2 = temp;
			}
			else
				break;
		}
		el_x1 = el_x2;
		el_y1 = el_y2;

		GraphicsPathEllipse.AddEllipse(new Rectangle(el_x2, el_y2, 10, 10));
		Ellipse.FillEllipse(EllipseBrush, new Rectangle(el_x2, el_y2, 10, 10));
	}
	searching.Enabled = true; //Активируем кнопку «Провести исследование»</pre>
<p>Напишем метод «MessageShow», который будет выводить сообщение на экран при завершении моделирования.<br />
void MessageShow(int type)<br />
{<br />
if(type == 1)<br />
MessageBox.Show(&laquo;Моделирование закончено!&raquo;);<br />
else<br />
MessageBox.Show(&laquo;Пьянчуга попал в люк&raquo;);<br />
}<br />
Теперь напишем объект «check», который осуществляет ряд проверок движения «пьяньчуги». Если «пьяньчуга» нашел выход или попал в один из люков, выводится соответствующее сообщение и моделирование прекращается.</p>
<pre class="brush: csharp;">int check(int type)
{
	//Конец пути пьянчуги
	if (PointUser.X &gt;= coord[0, 0].X &amp;&amp; PointUser.X &lt; = coord[0, 1].X &amp;&amp; PointUser.Y &lt;= coord[0, 1].Y)
	{
		if(type == 1)
			MessageShow(1);
		return -1;
	}
	//Пьянчуга попал в люк
	if (GraphicsPathEllipse.IsVisible(PointUser))
	{
		if(type == 1)
			MessageShow(2);
		return -1;
	}
	//Слева линия
	if (PointUser.X &lt;= coord[1, 0].X &amp;&amp; PointUser.Y &gt;= coord[1, 0].Y &amp;&amp; PointUser.Y &lt; = coord[1, 1].Y)
	{
		PointUser.X += shag;
	}
	//Верхняя
	if(PointUser.X &gt;= coord[2, 0].X &amp;&amp; PointUser.X &lt; = coord[2, 1].X &amp;&amp; PointUser.Y &lt;= coord[2, 0].Y)
	{
		PointUser.Y += shag;
	}
	//Верхняя 2
	if (PointUser.X &gt;= coord[6, 0].X &amp;&amp; PointUser.X &lt; = coord[6, 1].X &amp;&amp; PointUser.Y &lt;= coord[6, 0].Y)
	{
		PointUser.Y += shag;
	}
	//Правая линия
	if (PointUser.X &gt;= coord[3, 0].X &amp;&amp; PointUser.Y &gt;= coord[3, 0].Y &amp;&amp; PointUser.Y &lt; = coord[3, 1].Y)
	{
		PointUser.X -= shag;
	}
	//Нижняя
	if ((PointUser.X &gt;= coord[4, 0].X &amp;&amp; PointUser.X &lt; = coord[4, 1].X) &amp;&amp; PointUser.Y &gt;= coord[4, 1].Y)
	{
		PointUser.Y -= shag;
	}
	if ((PointUser.X &gt;= coord[7, 0].X &amp;&amp; PointUser.X &lt; = coord[7, 1].X) &amp;&amp; PointUser.Y &gt;= coord[7, 1].Y)
	{
		PointUser.Y -= shag;
	}
	if (PointUser.X &lt; = coord[8, 0].X &amp;&amp; PointUser.Y &gt;= coord[8, 0].Y &amp;&amp; PointUser.Y &lt; = coord[8, 1].Y)
	{
		PointUser.X += shag;
	}
	if ((PointUser.X &gt;= coord[10, 0].X &amp;&amp; PointUser.X &lt; = coord[10, 1].X) &amp;&amp; PointUser.Y &gt;= coord[10, 1].Y)
	{
		PointUser.Y -= shag;
	}
	if (PointUser.X &gt;= coord[9, 0].X &amp;&amp; PointUser.Y &gt;= coord[9, 0].Y &amp;&amp; PointUser.Y &lt; = coord[9, 1].Y)//Нижняя 2 справа
	{
		PointUser.X -= shag;
	}
	return 0;
}</pre>
<p>Следующие объекты и методы необходимы для проверки правильного указания коэффициентов вероятности перемещения и количества люков.</p>
<pre class="brush: csharp;">bool check_ver()
{
	double sum = Convert.ToDouble(go_up.Text) + Convert.ToDouble(go_down.Text) + Convert.ToDouble(go_right.Text) + Convert.ToDouble(go_left.Text);

	if (sum &gt; 1 || sum &lt; 1)
		MessageBox.Show(&quot;Сумма коэффициентов направленности превышает допустимое значение равное 1.&quot;);
	else if (Convert.ToInt32(kolvolukov.Text) &lt; 1 || Convert.ToInt32(kolvolukov.Text) &gt; 50)
		MessageBox.Show(&quot;Количество люков не может быть меньше 1 или больше 50.&quot;);
	else
		return true;

	return false;
}
//Запускается, когда происходит изменение Вероятности перемещения «Вверх»
private void go_up_TextChanged(object sender, EventArgs e)
{
	check_ver();
}
//Запускается, когда происходит изменение Вероятности перемещения «Вниз»
private void go_down_TextChanged(object sender, EventArgs e)
{
	check_ver();
}
//Запускается, когда происходит изменение Вероятности перемещения «Вправо»
private void go_right_TextChanged(object sender, EventArgs e)
{
	check_ver();
}
//Запускается, когда происходит изменение Вероятности перемещения «Влево»
private void go_left_TextChanged(object sender, EventArgs e)
{
	check_ver();
}
//Запускается, когда происходит изменение поля Количество люков
private void kolvolukov_TextChanged(object sender, EventArgs e)
{
	check_ver();
}</pre>
<p>Напишем методы, которые изменяют шаг движения. Если на объект выводятся «точки», шаг составляет 5, если цифры – 15. Создано для удобства вывода на экран.</p>
<pre class="brush: csharp;">private void pic_point_CheckedChanged(object sender, EventArgs e)
{
	shag = 5;
}
private void pic_char_CheckedChanged(object sender, EventArgs e)
{
	shag = 15;
}
//Объект «isPoint» возвращает положение координаты точки, если она есть в массиве mass_points
int isPoint(Point mass_nums, coord_points[] mass_points)
{
	for (int i = 0; i &lt; mass_points.Count(); i++)
	{
		if (mass_points[i].X == mass_nums.X &amp;&amp; mass_points[i].Y == mass_nums.Y)
			return i;
	}
	return -1;
}
//Метод «setCount» увеличивает счетчик попадания человека в точку на 1
void setCount(coord_points[] mass_points, int index)
{
	mass_points[index].count = mass_points[index].count + 1;
}
// Метод «listBox1_MouseDoubleClick» вызывается при двойном клике на объект «listBox1», где хранятся координаты перемещения «пьяньчуги». Метод выделяет красным цветом точку по указанной координате.
private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e)
{
	System.Drawing.Pen red = new Pen(Color.Red, 2);
	Graphics Ellipse = Graphics.FromHwnd(pictureBox.Handle);

	Ellipse.DrawEllipse(red, new Rectangle(mass_points[listBox1.Items.IndexOf(listBox1.Text)].X, mass_points[listBox1.Items.IndexOf(listBox1.Text)].Y, 2, 2));

}</pre>
<p>Наконец, метод «pictureBox_MouseDown», который осуществляет моделирование движения пьяного человека.</p>
<pre class="brush: csharp;">private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
	if (check_ver() == true)//Если все проверки прошли
	{
		PointUser.X = e.X; //Получаем X-координату точки
		PointUser.Y = e.Y; //Получаем Y-координату точки

		PointUser_For_searche.X = e.X;
		PointUser_For_searche.Y = e.Y;

		Line = Graphics.FromHwnd(pictureBox.Handle);
		System.Drawing.Graphics graph = Graphics.FromHwnd(pictureBox.Handle);

		System.Drawing.Pen WhiteSmoke = new Pen(Color.WhiteSmoke, 1);
		System.Drawing.Pen Black = new Pen(Color.Black, 2);
		EllipseDraw = new Rectangle(PointUser.X, PointUser.Y, 2, 2);
		Graphics Ellipse = Graphics.FromHwnd(pictureBox.Handle);
		Ellipse.DrawEllipse(Black, EllipseDraw);

		Random rnd = new Random();
		int count = 0, countiter = 0, c_left = 0, c_right = 0, c_up = 0, c_down = 0;
		double hod, left, right, up, down;
		coord_courses = new Point[Convert.ToInt32(count_steps.Text)];

		List&lt;Point&gt; mass_nums = new List&lt;point&gt;();

		for (int i = 1; i &lt; = Convert.ToInt32(count_steps.Text); i++)
		{
			if (rnd.Next(1, 5) != 1)//Если вероятность не «стоять на месте»
			{
				coord_courses[count] = PointUser;
				mass_nums.Add(PointUser);

				hod = rnd.NextDouble();
				up = Convert.ToDouble(go_up.Text);
				down = Convert.ToDouble(go_down.Text);
				right = up + down;
				left = up + down + Convert.ToDouble(go_right.Text);
//Если вероятность «идти влево»
				if (hod &gt; left &amp;&amp; hod &lt; left + Convert.ToDouble(go_left.Text))
				{
					PointUser.X -= shag;
					if (check(1) == -1)
						break;
					else
					{
						if (pic_point.Checked)
							Ellipse.DrawEllipse(Black, new Rectangle(PointUser.X, PointUser.Y, 2, 2));
					}
					c_left++;
				}
				else if (hod &gt; 0 &amp;&amp; hod &lt; up) //Если вероятность «идти вверх»
				{
					PointUser.Y -= shag;
					if (check(1) == -1)
						break;
					else
					{
						if (pic_point.Checked)
							Ellipse.DrawEllipse(Black, new Rectangle(PointUser.X, PointUser.Y, 2, 2));
					}
					c_up++;
				}
				else if (hod &gt; right &amp;&amp; hod &lt; right + Convert.ToDouble(go_right.Text)) //вправо
				{
					PointUser.X += shag;
					if (check(1) == -1)
						break;
					else
					{
						if (pic_point.Checked)
							Ellipse.DrawEllipse(Black, new Rectangle(PointUser.X, PointUser.Y, 2, 2));
					}
					c_right++;
				}
				else if (hod &gt; up &amp;&amp; hod &lt; up + down) //вниз
				{
					PointUser.Y += shag;
					if (check(1) == -1)
						break;
					else
					{
						if (pic_point.Checked)
							Ellipse.DrawEllipse(Black, new Rectangle(PointUser.X, PointUser.Y, 2, 2));
					}
					c_down++;
				}
			}
			countiter++;
		}
		count = c_down + c_left + c_right + c_up;

		count_iter.Text = countiter.ToString();
		distance.Text = (count).ToString();

		count_courses.Text = count.ToString();
		count_down.Text = c_down.ToString();
		count_up.Text = c_up.ToString();
		count_l.Text = c_left.ToString();
		count_r.Text = c_right.ToString();

		up = Convert.ToDouble(go_up.Text);
		down = Convert.ToDouble(go_down.Text);
		right = Convert.ToDouble(go_right.Text);
		left = Convert.ToDouble(go_left.Text);

		if (up &gt; down &amp;&amp; up &gt; right &amp;&amp; up &gt; left)
			isleovanie.Text = &quot;При к.н. (Вверх) пьянчуга прошел &quot; + Math.Round(((double)c_up / (double)count) * 100) + &quot;% пути&quot;;
		else if (down &gt; up &amp;&amp; down &gt; right &amp;&amp; down &gt; right)
			isleovanie.Text = &quot;При к.н. (Вниз) пьянчуга прошел &quot; + Math.Round(((double)c_down / (double)count) * 100) + &quot;% пути&quot;;
		else if (right &gt; up &amp;&amp; right &gt; left &amp;&amp; right &gt; down)
			isleovanie.Text = &quot;При к.н. (Вправо) пьянчуга прошел &quot; + Math.Round(((double)c_right / (double)count) * 100) + &quot;% пути&quot;;
		else if (left &gt; up &amp;&amp; left &gt; right &amp;&amp; left &gt; down)
			isleovanie.Text = &quot;При к.н. (Влево) пьянчуга прошел &quot; + Math.Round(((double)c_left / (double)count) * 100) + &quot;% пути&quot;;

		mass_points = new coord_points[mass_nums.Count];
		Point[] coord_courses2 = new Point[mass_nums.Count];
		int index = 0, j = 0;
		for (int i = 0; i &lt; mass_nums.Count; i++)
			if ((index = isPoint(mass_nums[i], mass_points)) &gt; -1)
			{
				setCount(mass_points, index);
			}
			else
			{
				mass_points[j].X = mass_nums[i].X;
				mass_points[j].Y = mass_nums[i].Y;
				mass_points[j].count = 1;
				j++;
			}

		for (int i = j - 1; i &gt;= 0; i--)
		{
			if (!pic_point.Checked)
			{
				if (i + 1 == j)
					graph.DrawString(mass_points[i].count.ToString(), new Font(&quot;Times New Roman&quot;, 8), new SolidBrush(Color.Red), mass_points[i].X - 3, mass_points[i].Y - 8);
				else
					graph.DrawString(mass_points[i].count.ToString(), new Font(&quot;Times New Roman&quot;, 8), new SolidBrush(Color.Black), mass_points[i].X - 3, mass_points[i].Y - 8);
			}
			listBox1.Items.Add(&quot;X:&quot; + mass_points[i].X + &quot;; Y:&quot; + mass_points[i].Y + &quot;; Кол-во:&quot; + mass_points[i].count);
		}
	}
}</pre>
<p>Напишем последний метод «searching_Click», чтобы завершить написание программы. Здесь выполняется исследование.</p>
<pre class="brush: csharp;">private void searching_Click(object sender, EventArgs e)
{
	Random rnd = new Random();
	int count = 0, countiter = 0, c_left = 0, c_right = 0, c_up = 0, c_down = 0;
	double hod, left, right, up, down;

	for (int sch = 1; sch &lt; = 10; sch++)
	{
		PointUser = PointUser_For_searche;
		for (int i = 1; i &lt;= Convert.ToInt32(count_steps.Text); i++)
		{
			if (rnd.Next(1, 5) != 1)
			{
				hod = rnd.NextDouble();
				up = Convert.ToDouble(go_up.Text);
				down = Convert.ToDouble(go_down.Text);
				right = up + down;
				left = up + down + Convert.ToDouble(go_right.Text);

				if (hod &gt; left &amp;&amp; hod &lt; left + Convert.ToDouble(go_left.Text)) //влево
				{
					PointUser.X -= shag;

					if (check(2) == -1)
						break;
					c_left++;
				}
				else if (hod &gt; 0 &amp;&amp; hod &lt; up) //вверх
				{
					PointUser.Y -= shag;

					if (check(2) == -1)
						break;
					c_up++;
				}
				else if (hod &gt; right &amp;&amp; hod &lt; right + Convert.ToDouble(go_right.Text)) //вправо
				{
					PointUser.X += shag;
					if (check(2) == -1)
						break;
					c_right++;
				}
				else if (hod &gt; up &amp;&amp; hod &lt; up + down) //вниз
				{
					PointUser.Y += shag;
					if (check(2) == -1)
						break;
					c_down++;
				}
			}
			countiter++;
		}
	}
	count = c_down + c_left + c_right + c_up;

	count_iter.Text = countiter.ToString();
	distance.Text = (count).ToString();

	count_courses.Text = count.ToString();
	count_down.Text = c_down.ToString();
	count_up.Text = c_up.ToString();
	count_l.Text = c_left.ToString();
	count_r.Text = c_right.ToString();

	up = Convert.ToDouble(go_up.Text);
	down = Convert.ToDouble(go_down.Text);
	right = Convert.ToDouble(go_right.Text);
	left = Convert.ToDouble(go_left.Text);

	if (up &gt; down &amp;&amp; up &gt; right &amp;&amp; up &gt; left)
	{
		isleovanie.Text = &quot;При к.н. (Вверх) пьянчуга прошел &quot; + Math.Round(((double)c_up / (double)count) * 100) + &quot;% пути&quot;;
		label10.Text = &quot;Среднее значение: &quot; + Math.Round((double)c_up / (double)count, 2).ToString();
	}
	else if (down &gt; up &amp;&amp; down &gt; right &amp;&amp; down &gt; right)
	{
		isleovanie.Text = &quot;При к.н. (Вниз) пьянчуга прошел &quot; + Math.Round(((double)c_down / (double)count) * 100) + &quot;% пути&quot;;
		label10.Text = &quot;Среднее значение: &quot; + Math.Round((double)c_down / (double)count, 2).ToString();
	}
	else if (right &gt; up &amp;&amp; right &gt; left &amp;&amp; right &gt; down)
	{
		isleovanie.Text = &quot;При к.н. (Вправо) пьянчуга прошел &quot; + Math.Round(((double)c_right / (double)count) * 100) + &quot;% пути&quot;;
		label10.Text = &quot;Среднее значение: &quot; + Math.Round((double)c_right / (double)count, 2).ToString();
	}
	else if (left &gt; up &amp;&amp; left &gt; right &amp;&amp; left &gt; down)
	{
		isleovanie.Text = &quot;При к.н. (Влево) пьянчуга прошел &quot; + Math.Round(((double)c_left / (double)count) * 100) + &quot;% пути&quot;;
		label10.Text = &quot;Среднее значение: &quot; + Math.Round((double)c_left / (double)count, 2).ToString();
	}
}</pre>
<p>После написание кода программы проверим ее работу:</p>
<ul>
<li>
<div style="text-align: justify;">Указать вероятности перемещения</div>
</li>
<li>
<div style="text-align: justify;">Указать количество люков и тактов</div>
</li>
<li>
<div style="text-align: justify;">Выбрать метод представления пути перемещения («Точки» или «Цифры»)</div>
</li>
<li>
<div style="text-align: justify;">Кликнуть по кнопке «Нарисовать местность»</div>
</li>
<li>
<div style="text-align: justify;">Кликнуть мышкой по области рисования «pictureBox»</div>
</li>
<li>
<div style="text-align: justify;">Посмеяться над «пьяньчугой»</div>
</li>
<li>
<div style="text-align: justify;">Кликнуть по кнопке «Провести исследование»</div>
</li>
</ul>
<p><strong><span style="text-decoration: underline;">Примеры работы программы:</span></strong></p>
<p>«Пьяньчуга» попал в люк:</p>
<p><img src="file:///C:/Users/EVTEEV/AppData/Local/Temp/moz-screenshot.png" alt="" /></p>
<p style="text-align: center;"><a href="http://statprog.ru/wp-content/picpiyan.jpg"><img class="aligncenter size-full wp-image-436" title="Пьяньчуга попал в люк" src="http://statprog.ru/wp-content/picpiyan.jpg" alt="Пьяньчуга попал в люк" width="550" height="350" /></a></p>
<p style="text-align: left;">«Пьяньчуга» нашел выход:</p>
<p style="text-align: center;"><a href="http://statprog.ru/wp-content/picpiyan2.jpg"><img class="aligncenter size-full wp-image-437" title="Пьяньчуга нашел выход" src="http://statprog.ru/wp-content/picpiyan2.jpg" alt="Пьяньчуга нашел выход" width="550" height="350" /></a></p>
<p>Данную статью Вы можете скачать в формате doc<br />
<a href="http://statprog.ru/wp-content/modelirovanie_piyanchugi.rar">Скачать Пьяньчуга &#8211; Моделирование движения пьяного человека на C#</a></p>
<p style="text-align: justify;"><span style="color: black; font-family: Times New Roman; font-size: 12pt;"><strong>Автор:<em> Евтеев Евгений Александрович<br />
</em></strong></span></p>
<p><span style="color: black; font-family: Times New Roman; font-size: 12pt;"><strong>Email:<em> evteev_e2003@mail.ru</em></strong></span></p>
]]></content:encoded>
			<wfw:commentRss>http://statprog.ru/2010/01/28/pyanchuga-modelirovanie-dvizheniya-pyanogo-cheloveka-na-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Построить треугольник, описать и вписать окружность на C#</title>
		<link>http://statprog.ru/2009/11/29/postroit-treugolnik-opisat-i-vpisat-okruzhnost-na-c/</link>
		<comments>http://statprog.ru/2009/11/29/postroit-treugolnik-opisat-i-vpisat-okruzhnost-na-c/#comments</comments>
		<pubDate>Sun, 29 Nov 2009 18:16:27 +0000</pubDate>
		<dc:creator>evteev</dc:creator>
				<category><![CDATA[C/C++/C#]]></category>

		<guid isPermaLink="false">http://statprog.ru/?p=268</guid>
		<description><![CDATA[В статье мы займемся рисованием, рисовать будем треугольник, вписанную и описанную окружность. Конечно, рисовать будет программа, код которой мы сейчас напишем. Координаты вершин треугольника будут находиться в структуре “Pt”. Для этого создадим переменные для работы со структурой и саму структуру. &#8230; <a href="http://statprog.ru/2009/11/29/postroit-treugolnik-opisat-i-vpisat-okruzhnost-na-c/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>В статье мы займемся рисованием, рисовать будем треугольник, вписанную и описанную окружность. Конечно, рисовать будет программа, код которой мы сейчас напишем.<br />
Координаты вершин треугольника будут находиться в структуре “Pt”. Для этого создадим переменные для работы со структурой и саму структуру.<span id="more-268"></span></p>
<pre class="brush: csharp;">Pt m1, m2, v1, v2, b1, b2;
public struct Pt
{
	double x;
	double y;
	public Pt(double a, double b)
	{
		x = a;
		y = b;
	}
	public double X
	{
		get { return x; }
		set { x = value; }
	}
	public double Y
	{
		get { return y; }
		set { y = value; }
	}
};</pre>
<p>Далее напишем функции для вычисления длин, углов треугольника и т.д. и процедуру для вывода графики на форму.<br />
Пишем функцию нахождения длины строны треугольника по заданным координатам. Будем использовать формулу нахождения расстояния между двумя точками.<br />
S = ((x2 &#8211; x1) ^2+ (y2-y1) ^2) ^ (1/2), где (x1, y1) и (x2, y2) &#8211; это координаты начала и конца отрезка.</p>
<pre class="brush: csharp;">double SideLength(double x1, double y1, double x2, double y2)
{
	double a = Math.Sqrt((x2 - x1) / 10 * (x2 - x1) / 10 + (y2 - y1) / 10 * (y2 - y1) / 10);
	return a * 10;
}</pre>
<p>Чтобы найти углы треугольника воспользуемся формулой скалярного произведения векторов<br />
cos(ang) = a/(s1*s2), где a &#8211; скалярное произведение векторов s1 и s2,а s1 и s2 &#8211; стороны треугольника (абсолютные величины векторов).</p>
<pre class="brush: csharp;">double Angles(Pt p1, Pt p2, Pt p3)
{
	double a = (p2.X - p1.X) * (p3.X - p1.X) + (p2.Y - p1.Y) * (p3.Y - p1.Y);
	double exp = a / SideLength(p1.X, p1.Y, p2.X, p2.Y) / SideLength(p1.X, p1.Y, p3.X, p3.Y);
	return Math.Acos(exp);
}</pre>
<p>Периметр находим как сумма длин трех сторон треугольника.</p>
<pre class="brush: csharp;">double Perimetr(double s1, double s2, double s3)
{
	return (s1 + s2 + s3);
}</pre>
<p><strong>Площадь треугольника</strong> находится с помощью формулы Герона:</p>
<pre class="brush: csharp;">Sqr = (p * (p - s1) * (p - s2) * (p - s3)) ^ (1 / 2), где p - полупериметр треугольника.
double Sqare(double s1, double s2, double s3)
{
	double p;
	p = (Perimetr(s1, s2, s3)) / 2;
	return Math.Sqrt((p * (p - s1) * (p - s2) * (p - s3)));
}</pre>
<p>Теперь найдем радиусы вписанной и описанной окружности.</p>
<pre class="brush: csharp;">double radius(double S, double p)
{
	return S / p;
}

double Radius(double S, double s1, double s2, double s3)
{
	return (s1 * s2 * s3) / (4 * S);
}</pre>
<p>И, наконец, процедура, которая будет осуществлять конечные вычисления, и рисовать окружность на форме программы.</p>
<pre class="brush: csharp;">void DescrCircle(double R, int x01, int y01, int x02, int y02, double l1, double m1, double l2, double m2)
{
	double X, Y;
	if ((l1 != 0) &amp;amp;&amp;amp; ((m1 / l1) - (m2 / l2) != 0) &amp;amp;&amp;amp; (l2 != 0))
	{
		X = ((m1 / l1) * x01 - y01 - (m2 / l2) * x02 + y02) / ((m1 / l1) - (m2 / l2));
		Y = (m1 * X - m1 * x01 + l1 * y01) / l1;
		System.Drawing.Graphics graph = this.CreateGraphics();
		System.Drawing.Pen color = new Pen(Color.Blue, 1);
		graph.DrawEllipse(color, (int)X, (int)Y, 1, 1); //рисуем центр окружности
		graph.DrawEllipse(color, (int)X - (float)R, (int)Y - (float)R, (float)R * 2, (float)R * 2); //рисуем окружность
	}
}</pre>
<p>Процедура кнопки, которая будет вызывать всю процедуру рисования треугольника и окружностей.</p>
<pre class="brush: csharp;">private void button1_Click_1(object sender, EventArgs e)</pre>
<p>Объявим нужные переменные и занесем в структуру координаты вершин треугольника из текстовых полей на форме.</p>
<pre class="brush: csharp;">double s1 ,s2 ,s3 ,S ,p ,r, R, ang1, ang2, ang3, x1, x2, y1, y2, det;
znach.Items.Clear();

Pt[] a = new Pt[3];
a[0].X = Convert.ToDouble(Ax.Text);
a[0].Y = Convert.ToDouble(Ay.Text);
a[1].X = Convert.ToDouble(Bx.Text);
a[1].Y = Convert.ToDouble(By.Text);
a[2].X = Convert.ToDouble(Cx.Text);
a[2].Y = Convert.ToDouble(Cy.Text);</pre>
<p>Нарисуем форме три линии, которые будут составлять наш треугольник и названия вершин A, B и C.</p>
<pre class="brush: csharp;">System.Drawing.Graphics graph = this.CreateGraphics();
System.Drawing.Pen red = new Pen(Color.Red, 1);

graph.DrawLine(red, (int)a[0].X, (int)a[0].Y, (int)a[1].X, (int)a[1].Y);
graph.DrawString(&quot;A&quot;, new Font(&quot;Times New Roman&quot;, 12), new SolidBrush(Color.Black), (int)a[0].X, (int)a[0].Y);
graph.DrawLine(red, (int)a[1].X, (int)a[1].Y, (int)a[2].X, (int)a[2].Y);
graph.DrawString(&quot;B&quot;, new Font(&quot;Times New Roman&quot;, 12), new SolidBrush(Color.Black), (int)a[1].X, (int)a[1].Y);
graph.DrawLine(red, (int)a[0].X, (int)a[0].Y, (int)a[2].X, (int)a[2].Y);
graph.DrawString(&quot;C&quot;, new Font(&quot;Times New Roman&quot;, 12), new SolidBrush(Color.Black), (int)a[2].X, (int)a[2].Y);</pre>
<p>Используя написанные функции, найдем длины сторон, полупериметр, площадь, радиусы вписанной и описанной окружности и углы треугольника.</p>
<pre class="brush: csharp;">s1 = SideLength(a[0].X, a[0].Y, a[1].X, a[1].Y);
s2 = SideLength(a[1].X, a[1].Y, a[2].X, a[2].Y);
s3 = SideLength(a[2].X, a[2].Y, a[0].X, a[0].Y);

p = (Perimetr(s1, s2, s3)) / 2;
S = Sqare(s1, s2, s3);

r = radius(S, p);
R = Radius(S, s1, s2, s3);

ang1 = Angles(a[2], a[0], a[1]);
ang2 = Angles(a[0], a[1], a[2]);
ang3 = Angles(a[1], a[2], a[0]);</pre>
<p>Выведем на форму все эти вычисленные значения в ListBox “znach”.</p>
<pre class="brush: csharp;">znach.Items.Add(&quot;Длина AB: &quot; + s1);
znach.Items.Add(&quot;Длина BC: &quot; + s2);
znach.Items.Add(&quot;Длина AC: &quot; + s3);
znach.Items.Add(&quot;Полупериметр: &quot; + p);
znach.Items.Add(&quot;Площадь: &quot; + S);
znach.Items.Add(&quot;Радиус вписанной о.: &quot; + r);
znach.Items.Add(&quot;Радиус описанной о.: &quot; + R);
znach.Items.Add(&quot;Угл CAB: &quot; + ang1);
znach.Items.Add(&quot;Угл ABC: &quot; + ang2);
znach.Items.Add(&quot;Угл BCA: &quot; + ang3);</pre>
<p>Найдем середины сторон s1 и s2.</p>
<pre class="brush: csharp;">m1.X = (a[0].X + a[1].X) / 2;
m1.Y = (a[0].Y + a[1].Y) / 2;
m2.X = (a[1].X + a[2].X) / 2;
m2.Y = (a[1].Y + a[2].Y) / 2;</pre>
<p>Необходимо повернуть точки на угол 90 градусов.<br />
Поворачиваем точку а[2] вокруг середины стороны:</p>
<pre class="brush: csharp;"> x1 = a[2].X; y1 = a[2].Y;
x1 -= m2.X; y1 -= m2.Y;
b1.X = x1 * Math.Cos(Math.PI / 2) - y1 * Math.Sin(Math.PI / 2);
b1.Y = x1 * Math.Sin(Math.PI / 2) + y1 * Math.Cos(Math.PI / 2);
b1.X += m2.X; b1.Y += m2.Y;
v1.X = b1.X - m2.X; v1.Y = b1.Y - m2.Y;</pre>
<p>Поворачиваем точку а[0] вокруг середины стороны s1:</p>
<pre class="brush: csharp;">x1 = a[0].X; y1 = a[0].Y;
x1 -= m1.X; y1 -= m1.Y;
b2.X = x1 * Math.Cos(Math.PI / 2) - y1 * Math.Sin(Math.PI / 2);
b2.Y = x1 * Math.Sin(Math.PI / 2) + y1 * Math.Cos(Math.PI / 2);
b2.X += m1.X; b2.Y += m1.Y;
v2.X = b2.X - m1.X; v2.Y = b2.Y - m1.Y;</pre>
<p>Вызовем нашу процедуру для вывода графики и построим описанную окружность с центром в точке пересечения серединных перепендикуляров.</p>
<pre class="brush: csharp;">DescrCircle(R, (int)m1.X, (int)m1.Y, (int)m2.X, (int)m2.Y, v2.X, v2.Y, v1.X, v1.Y);</pre>
<p>int coef1 = 1, coef2 = 1; //коэффициенты,указывающие напрвление поворота<br />
Вычисляем знак третьей координаты векторного произведения векторов, между которыми строится биссектриса.</p>
<pre class="brush: csharp;">det = (a[1].X - a[0].X) * (a[2].Y - a[0].Y) - (a[2].X - a[0].X) * (a[1].Y - a[0].Y);
if (det &amp;gt; 0) coef1 = -1;
	det = (a[1].X - a[2].X) * (a[0].Y - a[2].Y) - (a[0].X - a[2].X) * (a[1].Y - a[2].Y);
if (det &amp;gt; 0)
	coef2 = -1;</pre>
<p>Поворачиваем точку a[2] вокруг a[0] на угол равный половине угла ang2</p>
<pre class="brush: csharp;">x1 = a[2].X; y1 = a[2].Y;
x1 -= a[0].X; y1 -= a[0].Y;
b1.X = x1 * Math.Cos(coef1 * ang2 / 2) - y1 * Math.Sin(coef1 * ang2 / 2);
b1.Y = x1 * Math.Sin(coef1 * ang2 / 2) + y1 * Math.Cos(coef1 * ang2 / 2);
b1.X += a[0].X; b1.Y += a[0].Y;
v1.X = b1.X - a[0].X; v1.Y = b1.Y - a[0].Y;

x2 = a[0].X; y2 = a[0].Y;
x2 -= a[2].X; y2 -= a[2].Y;
b2.X = x2 * Math.Cos(coef2 * ang1 / 2) - y2 * Math.Sin(coef2 * ang1 / 2);
b2.Y = x2 * Math.Sin(coef2 * ang1 / 2) + y2 * Math.Cos(coef2 * ang1 / 2);
b2.X += a[2].X; b2.Y += a[2].Y;
v2.X = b2.X - a[2].X; v2.Y = b2.Y - a[2].Y; //v1.x v1.y- координаты направляющего вектора биссектрисы</pre>
<p>И последнее, что мы делаем это выполняем построение вписанной окружности с центром в точке пересечения биссектрисс.</p>
<pre class="brush: csharp;">DescrCircle(r, (int)a[2].X, (int)a[2].Y, (int)a[0].X, (int)a[0].Y, v2.X, v2.Y, v1.X, v1.Y);</pre>
<p><img class="aligncenter size-medium wp-image-270" title="buid_tr_okr" src="http://statprog.ru/wp-content/buid_tr_okr-300x273.jpg" alt="buid_tr_okr" width="300" height="273" /></p>
<p>Треугольник и две окружности построены, для решения этой задачи нам понадобились небольшие знания C# и геометрии.<br />
<strong>Автор</strong>: <em>Евтеев Евгений Александрович</em><br />
<strong>Email</strong>: <em>evteev_e2003@mail.ru</em></p>
]]></content:encoded>
			<wfw:commentRss>http://statprog.ru/2009/11/29/postroit-treugolnik-opisat-i-vpisat-okruzhnost-na-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Найти наименьшее общее кратное, используя универсальный алгоритм</title>
		<link>http://statprog.ru/2009/11/16/najti-naimenshee-obshhee-kratnoe-ispolzuya-universalnyj-algoritm/</link>
		<comments>http://statprog.ru/2009/11/16/najti-naimenshee-obshhee-kratnoe-ispolzuya-universalnyj-algoritm/#comments</comments>
		<pubDate>Mon, 16 Nov 2009 18:40:27 +0000</pubDate>
		<dc:creator>evteev</dc:creator>
				<category><![CDATA[C/C++/C#]]></category>
		<category><![CDATA[НОК]]></category>

		<guid isPermaLink="false">http://statprog.ru/?p=236</guid>
		<description><![CDATA[В предшествующей статье я рассказал, как найти наибольшее общее кратное двух чисел, используя алгоритм вычисления НОД. В этой статей мы с вами напишем универсальный алгоритм нахождения НОК. Этот алгоритм позволяет найти НОК не только для двух чисел, но для множества &#8230; <a href="http://statprog.ru/2009/11/16/najti-naimenshee-obshhee-kratnoe-ispolzuya-universalnyj-algoritm/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>В предшествующей статье я рассказал, как найти наибольшее общее кратное двух чисел, используя алгоритм вычисления <a href="http://statprog.ru/2009/04/04/poisk-naibolshego-obshhego-delitelya-dvux-chisel/">НОД</a>. В этой статей мы с вами напишем универсальный алгоритм нахождения <a href="http://statprog.ru/2009/11/16/najti-naimenshee-obshhee-kratnoe-ispolzuya-agloritm-nod/">НОК</a>. Этот алгоритм позволяет найти <a href="http://statprog.ru/2009/11/16/najti-naimenshee-obshhee-kratnoe-ispolzuya-agloritm-nod/">НОК</a> не только для двух чисел, но для множества чисел.<span id="more-236"></span><br />
Начнем с создания формы проекта, примерная форма показана на рисунке:<br />
<img src="http://statprog.ru/wp-content/app_find_nok_2-300x174.gif" alt="app_find_nok_2" title="app_find_nok_2" width="300" height="174" class="aligncenter size-medium wp-image-239" /></p>
<p>Форму создали, разместили необходимые объекты на ней. Теперь будем заниматься написанием кода программы. Числа, для которых будет производиться поиск НОК, будут вводиться через пробел. Для того, что их читать из поля “n_gr ” напишем функцию.</p>
<pre class="brush: csharp;">string[] nums(string str, int f_m)
{
	string[] numbers = new string[f_m + 1];
	f_m = 0;
	for (int i = 0; i &lt; str.Length; i++)
	{
		if (str.Substring(i, 1) != &quot; &quot;)
			numbers[f_m] += str.Substring(i, 1);
		else
			f_m++;
	}

	return numbers;
}</pre>
<p>Входные параметры “str” и “f_m” – это строка с числа и количество чисел соответственно. Создаем массив размерностью “f_m” и начинаем “выдирать” числа из строки и добавлять их в массив “numbers”. Функция возращает массив с числами из строки.</p>
<p>Теперь процедура события клика по кнопке “find”:</p>
<pre class="brush: csharp;">private void find_Click(object sender, EventArgs e)
{
	string s = n_gr.Text;
	int i = 0, f_m = 0;
	while (i &lt; s.Length)
	{
		if (s.Substring(i, 1) == &quot; &quot;)
			f_m++;
		i++;
	}
	string[] numbers = new string[f_m + 1];
	numbers = nums(s, f_m);
	int c = 2;
	bool nok = true;
	for (; ; )
	{
		for (i = 0; i &lt; numbers.Length; i++)
			if (numbers[i] != &quot;&quot;)
				if (c % Convert.ToInt32(numbers[i]) == 0)
				{
					if (i == 0 || nok == true)
						nok = true;
				}
				else
					nok = false;
		if (nok == true)
		{
			n_nok2.Text = Convert.ToString(c);
			break;
		}
		if (c &gt;= 1000000)
		{
			n_nok2.Text = &quot;НОК для данных чисел не найден!&quot;;
			break;
		}
		c++;
	}
}</pre>
<p>Здесь сначала вычисляется количество чисел в введенной строке, создается и заполняется массив с числами. Затем используется следующий алгоритм вычисления НОК: постоянно увеличивающееся число 2 делим на каждое из введенных чисел и НОК будет найден в том случае, когда остаток от деления на каждое число будет равен нулю. Если НОК найден или количество проходов цикла перевалило за 1000000 прекращаем работу программы, выводим соответствующий результат ее работы.</p>
<p><img src="http://statprog.ru/wp-content/app_find_nok_2_res-300x174.gif" alt="app_find_nok_2_res" title="app_find_nok_2_res" width="300" height="174" class="aligncenter size-medium wp-image-240" /><br />
На рисунке показан пример удачного поиска НОК, универсальный алгоритм работает правильно.</p>
<blockquote><p><strong>Автор</strong>: <em>Евтеев Евгений Александрович</em><br />
<strong>Email</strong>: <em>evteev_e2003@mail.ru</em></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://statprog.ru/2009/11/16/najti-naimenshee-obshhee-kratnoe-ispolzuya-universalnyj-algoritm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Найти наименьшее общее кратное (НОК), используя алгоритм НОД</title>
		<link>http://statprog.ru/2009/11/16/najti-naimenshee-obshhee-kratnoe-ispolzuya-agloritm-nod/</link>
		<comments>http://statprog.ru/2009/11/16/najti-naimenshee-obshhee-kratnoe-ispolzuya-agloritm-nod/#comments</comments>
		<pubDate>Sun, 15 Nov 2009 21:18:20 +0000</pubDate>
		<dc:creator>evteev</dc:creator>
				<category><![CDATA[C/C++/C#]]></category>

		<guid isPermaLink="false">http://statprog.ru/?p=233</guid>
		<description><![CDATA[Сегодня мы поговорим о наименьшем общем кратном (НОК) двух чисел и как его найти. НОК – это целое число, которое делится на два любых целых числа. Например, даны два числа 2 и 3, НОК этих чисел равен 6, т.е. число &#8230; <a href="http://statprog.ru/2009/11/16/najti-naimenshee-obshhee-kratnoe-ispolzuya-agloritm-nod/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Сегодня мы поговорим о наименьшем общем кратном (<strong>НОК</strong>) двух чисел и как его найти. <strong>НОК</strong> – это целое число, которое делится на два любых целых числа. Например, даны два числа 2 и 3, <strong>НОК</strong> этих чисел равен 6, т.е.  число 6 делится и на 2 и на 3.<br />
Чтобы написать данную программу на <strong>C#</strong> будем использовать ко всему прочему <strong>алгоритм Евклида</strong> нахождение <strong><a href="http://statprog.ru/2009/04/04/poisk-naibolshego-obshhego-delitelya-dvux-chisel/">НОД</a></strong>. Лучше всего реализовать алгоритм в рекурсивной функции.<span id="more-233"></span></p>
<pre class="brush: csharp;">int nod_recur(int num1, int num2)
{
	int n = num1 % num2;
	num1 = num2;
	num2 = n;
	if (n &gt; 0)
		return nod_recur(num1, num2);
	else
		return num1;
}</pre>
<p>Как работает эта функция, я рассказывать не буду, т.к. вы можете прочитать это в другой моей статье, посвященной этому алгоритму. Ну и собственно код процедуры события клика по кнопке “button1”:</p>
<pre class="brush: csharp;">private void button1_Click(object sender, EventArgs e)
{
	int num1 = Convert.ToInt32(n1.Text);
	int num2 = Convert.ToInt32(n2.Text);
	n_nok.Text = Convert.ToString(num1 * num2 / nod_recur(num1, num2));
}</pre>
<p>Как вы видите из кода, здесь происходит считывание двух введенных чисел в переменные и вычисление <strong>НОК</strong>. Можно сказать, что <strong>НОК</strong> вычисляется в два действия: перемножаются два и результат от умножения делится на результат вычисления <strong><a href="http://statprog.ru/2009/04/04/poisk-naibolshego-obshhego-delitelya-dvux-chisel/">НОД</a></strong> этих двух чисел. Результат вычисления <strong>НОК</strong> записывается в текстовое поле “n_nok”.</p>
<p>Вы думали, что написать такую программу будет не так просто? Извините, что разочаровал вас. В другой статье, я расскажу вам, как вычислить <strong>НОК</strong> для двух и более чисел, так называемый <strong>универсальный алгоритм</strong>.</p>
<blockquote><p><strong>Автор</strong>: <em>Евтеев Евгений Александрович</em><br />
<strong>Email</strong>: <em>evteev_e2003@mail.ru</em></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://statprog.ru/2009/11/16/najti-naimenshee-obshhee-kratnoe-ispolzuya-agloritm-nod/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Перевод десятичного числа в двоичное на VC++</title>
		<link>http://statprog.ru/2009/11/04/perevod-desyatichnogo-chisla-v-dvoichnoe-na-vc/</link>
		<comments>http://statprog.ru/2009/11/04/perevod-desyatichnogo-chisla-v-dvoichnoe-na-vc/#comments</comments>
		<pubDate>Tue, 03 Nov 2009 22:55:54 +0000</pubDate>
		<dc:creator>evteev</dc:creator>
				<category><![CDATA[C/C++/C#]]></category>

		<guid isPermaLink="false">http://statprog.ru/?p=33</guid>
		<description><![CDATA[Перевод из десятичной системы в двоичную Как преобразовать десятичное число в двоичный вид на VC++? Ответ на этот вопрос мы и рассмотрим в этой статье. Мы будем использовать всем известный метод, нахождения двоичного представления десятичного числа – деление числа на &#8230; <a href="http://statprog.ru/2009/11/04/perevod-desyatichnogo-chisla-v-dvoichnoe-na-vc/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h1 style="font-size: 15px; font-weight: bold;">Перевод из десятичной системы в двоичную</h1>
<h2 style="font-size: 14px; font-weight: bold;">Как преобразовать десятичное число в двоичный вид на VC++?</h2>
<p>Ответ на этот вопрос мы и рассмотрим в этой статье. Мы будем использовать всем известный метод, нахождения двоичного представления десятичного числа – деление числа на 2. Все эти преобразования будут находиться в процедуре “Dec2Bin(int ch)”, где “ch”- число в десятичном представлении, которое собственно мы будем <strong>декодировать в двоичное</strong>. <span id="more-33"></span></p>
<p>До всего прочего нужно сначала объявить переменную “n” как константу: “const int n = 32;” Она отвечает за размерность массива “s[n]”, в который будет помещаться <strong>двоичное</strong> представление числа.<br />
И так, давайте рассмотрим процедуру “Dec2Bin(int ch)”, которая будет <strong>преобразовать десятичное число в двоичный вид</strong>. Что в этой процедуре мы делаем?</p>
<p>Наше число в 10-м виде делим на 2 с остатком и если при делении получается число с остатком, то в i-й элемент массива “s[i]” мы записываем число 1, в противном случае записываем 0. Этому числу “ch” приравниваем значение равное “ch”деленное на 2, эти действия выполняются пока число “ch” не будут равно нулю.</p>
<p>Дальше проверяем, если наше 10-е число отрицательное инвертируем значения массива “s[n]”, т.е. число 1 заменяем на 0 и число 0 на 1. Это правило распространяется только на отрицательные числа. Затем приводим наш массив “s[n]” в нормальный вид, инвертируя значения до тех пор, пока ни встретится значение равное 0. В конце концов, прогоняя массив по циклу “for” выводим двоичное представление числа в 10-м виде. Вот и все, теперь посмотрите, что получилось:</p>
<p>Процедура “Dec2Bin(int ch)” -<strong>Перевод из десятичной системы в двоичную</strong></p>
<pre class="brush: cpp;">void Dec2Bin(int ch)
{
	int i, ch2, s[n];
	ch2 = ch;
	for (i = 0; i &amp;lt; n; i++)
	s[i] = 0;
	for (i = 0; ch != 0; i++)
	{
		s[i] = abs(ch) % 2; //текущему значению массива s присваиваем 1 или 0
		ch = abs(ch) / 2;
	}
	if (ch2 &amp;lt; 0)
	{
		for (i = n - 1; i &amp;gt;= 0; i--)
			if (s[i] == 1)
				s[i] = 0;
			else
				s[i] = 1;
	}
	for (i = 0; i &amp;lt; n; i++)
		if (s[i] == 1)
			s[i] = 0;
		else
		{
			s[i] = 1;
			break;
		}
	wcout &amp;lt;&amp;lt; L&quot;Двоичное представление :&quot; &amp;lt;&amp;lt; endl;
	for (i = n - 1; i &amp;gt;= 0; i--) //цикл вывода массива с введенным числом
		cout &amp;lt;&amp;lt; s[i]; //представленным в двоичной системе счисления
}</pre>
<p>Число в 2-м виде получили, но разве вам не хочется декодировать его обратно? Для начала напишем функции возведения числа в степень и получения длины массива, они нам понадобятся.</p>
<p>Функция “len(char str[])”:</p>
<pre class="brush: cpp;">int len(char str[])
{
	int i = 0;
	while (str[i] != 0)
		i++;
	return i-1;
}</pre>
<p>Функция “stepen(int ch, int st)”:</p>
<pre class="brush: cpp;">int stepen(int ch, int st)
{
	int a = 1;
	for(int i = 0; i &amp;lt; st; i++)
		a *= ch;
	return a;
}</pre>
<p>Функция “len(char str[])” возвращает длину массива “str[]”, а “stepen(int ch, int st)” возводит число 2 в степень “st”.</p>
<h3 style="font-size: 15px; font-weight: bold;">Перевод из двоичной системы в десятичную</h3>
<p>Теперь рассмотрим функцию “Bin2Dec (char m[])”, где “m[]”- это есть массив двоичных данных, в которых спрятано число. Если первый символ в массиве равен ‘1’, т.е. наше число отрицательное, то каждый символ в массиве до первой найденной ‘1’ инвертируем и после этого снова выполняет замену всех символов массива на ‘0’, если этот символ это ‘1’ или на ‘1’ соответственно. Затем непосредственно выполняем перевод в 10-й вид, используя нашу функцию возведения в степень. Код приведен ниже:</p>
<p>Функция “Bin2Dec (char m[])” &#8211; <strong>Перевод из двоичной системы в десятичную</strong></p>
<pre class="brush: cpp;">int Bin2Dec (char m[])
{
	int i, deca=0, j = 0, q = 1;
	if (m[0] == '1')
	{
		for (i = n - 1; i &amp;gt;= 0; i--)
			if (m[i] == '0')
				m[i] = '1';
			else
			{
				m[i] = '0';
				break;
			}
		for (i = 0; i &amp;lt; n; i++)
			if (m[i] == '1')
				m[i] = '0';
			else
				m[i] = '1';
		q*=-1;
	}
	for (i = n - 1; i &amp;gt;= 0; i--, j++)
		if(m[i] == '1')
			deca += stepen(2,j);
	return deca*q;
}</pre>
<p>Ну и, наконец, главная функция, с которой начинается работа нашего приложения. Здесь происходит ввод данных и вывод результата работы программы на экран пользователя.</p>
<p>Главный метод:</p>
<pre class="brush: cpp;">[/cpp]int main()
{
	wcout.imbue(locale("rus_rus.866"));
	int ch;
	char c[n];
	wcout &lt;&lt; L"Введите число (десятичное):" &lt;&lt; endl; //вывод сообщения на экран
	cin &gt;&gt; ch; //ввод значения с клавиатуры
	Dec2Bin(ch);
	/*------------------------------------------------------------------------*/
	wcout &lt;&lt; L"\n\nВведите число (двоичное):" &lt;&lt; endl; //вывод сообщения на экран
	cin&gt;&gt;c; //ввод значения с клавиатуры
	wcout &lt;&lt; L"Десятичное представление :" &lt;&lt; endl &lt;&lt; Bin2Dec(c) &lt;&lt; endl; //выводим на экран число в 10-й системе счисления
	system("pause");
	return 1;
}[cpp]</pre>
<p>Используя данное приложение, вы с легкостью сможете переводить числа из десятичной системы счисления в двоичный вид и, наоборот, из двоичной системы счисления в десятичный вид. Желаю вам удачи!</p>
<blockquote><p><strong>Автор</strong>: Евтеев Евгений Александрович<br />
<strong>Email</strong>: evteev_e2003@mail.ru</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://statprog.ru/2009/11/04/perevod-desyatichnogo-chisla-v-dvoichnoe-na-vc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Реализовать алгоритм сжатия данных RLE</title>
		<link>http://statprog.ru/2009/06/02/realizovat-algoritm-szhatiya-dannyx-rle/</link>
		<comments>http://statprog.ru/2009/06/02/realizovat-algoritm-szhatiya-dannyx-rle/#comments</comments>
		<pubDate>Mon, 01 Jun 2009 21:35:52 +0000</pubDate>
		<dc:creator>evteev</dc:creator>
				<category><![CDATA[C/C++/C#]]></category>

		<guid isPermaLink="false">http://statprog.ru/?p=319</guid>
		<description><![CDATA[Перед написанием программы разберемся, в чем суть алгоритма RLE? Суть алгоритма состоит в том, что последовательность из n одинаковых символов k заменяется парой символов nk. Например, нужно закодировать строку “aaaaarooow”, после кодирования по алгоритму RLE получаем сжатую строку вида “5ar3ow”. &#8230; <a href="http://statprog.ru/2009/06/02/realizovat-algoritm-szhatiya-dannyx-rle/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Перед написанием программы разберемся, в чем суть алгоритма RLE? Суть алгоритма состоит в том, что последовательность из n одинаковых символов k заменяется парой символов nk. Например, нужно закодировать строку “aaaaarooow”, после кодирования по алгоритму RLE получаем сжатую строку вида “5ar3ow”. Кодированная строка на 4 символа меньше, соответственно эффективность алгоритма доказана. Теперь можно приступить к реализации данного алгоритма в виде программного кода на C#.<span id="more-319"></span></p>
<p>Текст, который нужно будет кодировать, получим из текстового поля “text_input” и запишем в строковую переменную “str1”. Далее будем пробегать по каждому символу в этой строке, получать текущий символ в строковую переменную “ch”. В том случае, если данный символ равен следующему, продолжаем поиск количества таких символов, начиная текущей позиции в строке.</p>
<p>После всего этого формируем кодируемую строку равную количеству найденных символов и самому символу, которых повторяется друг за другом n-e количество раз. Если найден только один символ строка принимает значение равное этому символу.<br />
Все выше описанные операции выполняются до тех пор, пока не будет достигнут конец файла.</p>
<blockquote><p><code>            string str1 = text_input.Text, str = "", ch = "";<br />
            int i, k, j;<br />
            for (i = 0; i < str1.Length; ) // от 0 до длины строки<br />
            {<br />
                ch = str1.Substring(i, 1); // получаем текущий символ из строки str1<br />
                k = 0; //счетчик количества повторяющихся символов<br />
                if (i == str1.Length - 1) // если последний символ<br />
                {<br />
                    str += Convert.ToString(ch);<br />
                    break; //выходим из цикла<br />
                }<br />
                if (str1.Substring(i + 1, 1) == ch)<br />
                {<br />
                    for (j = i; j < str1.Length; j++)<br />
                    {<br />
                        if (str1.Substring(j, 1) == ch)//если текущий символ равен символу из строки ch<br />
                        {<br />
                            k++;//увеличиваем счетчик<br />
                        }<br />
                        else<br />
                            break; //выходим из цикла<br />
                    }<br />
                    i = j;<br />
                }<br />
                else<br />
                    i++;<br />
                if (k != 0)<br />
                    str += Convert.ToString(k) + Convert.ToString(ch);<br />
                else<br />
                    str += Convert.ToString(ch);</p>
<p>            }<br />
            text_output.Text = str;<br />
            button2.Enabled = true;</code></code></p></blockquote>
<p>Кодировку успешно выполнили, теперь напишем декодировку строки, кодированную при помощи алгоритма RLE. Декодирование закодированной строки выполняется путем поиска числа, которое является количеством повторений символа и самого символа.<br />
И так, получаем закодированную строку из текстового поля “textBox1” и записывает полученный текст в переменную “str1”. При каждом проходе цикла, который выполняется, пока недостигнут последний символ, записываем в переменную “ch” текущий символ и если он является цифрой, выполняем поиск цифр идущих друг за другом. Тем самым последовательность найденных цифр будет представлять собой число, являющееся количеством повторений символа, идущего сразу же после этой последовательности. В конце в строковую переменную “str” записываем букву столько раз, сколько равно значение числа.</p>
<blockquote><p><code>           string str1 = textBox1.Text, str = "", ch = "", s = "", symb = "";<br />
            int i, k = 0, j;<br />
            for (i = 0; i < str1.Length; )<br />
            {<br />
                ch = str1.Substring(i, 1); // текущий символ i<br />
                k = 0;<br />
                s = "";<br />
                if ("0123456789".Contains(ch)) // если символ ch является цифрой<br />
                {<br />
                    for (j = i; j < str1.Length; j++)<br />
                    {<br />
                        if ("0123456789".Contains(str1.Substring(j, 1))) // если текущий символ j является цифрой<br />
                        {<br />
                            s += str1.Substring(j, 1);<br />
                        }<br />
                        else<br />
                            break;<br />
                    }<br />
                    symb = str1.Substring(j, 1); // получаем букву<br />
                    i = j + 1;<br />
                }<br />
                else<br />
                    i++;<br />
                if (s.Length != 0)<br />
                {<br />
                    for (j = 0; j < Convert.ToInt32(s); j++) // декодирование буквы<br />
                        str += symb;<br />
                }<br />
                else<br />
                    str += Convert.ToString(ch);<br />
            }<br />
            out_shifr.Text = str;</code></code></p></blockquote>
<p>В данной программе реализовано кодирование и декодирование строки, используя алгоритм сжатия данных RLE.</p>
<blockquote><p><strong>Автор</strong>: <em>Евтеев Евгений Александрович</em><br />
<strong>Email</strong>: <em>evteev_e2003@mail.ru</em></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://statprog.ru/2009/06/02/realizovat-algoritm-szhatiya-dannyx-rle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Получить последовательность a1…an цифр 0,1,2, в которой нет смежных одинаковых участков</title>
		<link>http://statprog.ru/2009/05/18/poluchit-posledovatelnost-a1%e2%80%a6an-cifr-012-v-kotoroj-net-smezhnyx-odinakovyx-uchastkov/</link>
		<comments>http://statprog.ru/2009/05/18/poluchit-posledovatelnost-a1%e2%80%a6an-cifr-012-v-kotoroj-net-smezhnyx-odinakovyx-uchastkov/#comments</comments>
		<pubDate>Mon, 18 May 2009 15:12:21 +0000</pubDate>
		<dc:creator>evteev</dc:creator>
				<category><![CDATA[C/C++/C#]]></category>

		<guid isPermaLink="false">http://statprog.ru/?p=301</guid>
		<description><![CDATA[Программа должна генерировать последовательность любой длины из цифр 0, 1 и 2, но она не должна содержать в себе одинаковых участков таких как, например, последовательность 1010 – недопустимо, т.к. участки 10 и 10 расположены один за другим; последовательность 120120 – &#8230; <a href="http://statprog.ru/2009/05/18/poluchit-posledovatelnost-a1%e2%80%a6an-cifr-012-v-kotoroj-net-smezhnyx-odinakovyx-uchastkov/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Программа должна генерировать последовательность любой длины из цифр 0, 1 и 2, но она не должна содержать в себе одинаковых участков таких как, например, последовательность 1010 – недопустимо, т.к. участки 10 и 10 расположены один за другим; последовательность 120120 – имеются два одинаковых участка 120 и 120.</p>
<p>Напишем функцию “check_str”, которая будет возвращать “false” в случае если найден одинаковый участок в последовательности “s”.</p>
<blockquote><p><code>Boolean check_str(string s)<br />
        {<br />
            string start, end;<br />
            for (int i = 1; i < = s.Length / 2; i++)<br />
            {<br />
                start = s.Substring(0, s.Length - i);<br />
                end = s.Substring(s.Length - i, i);<br />
                if (start.Length < end.Length)<br />
                    return true;<br />
                if (start.Substring(start.Length - i, i) == end)<br />
                    return false;<br />
            }<br />
            return true;<br />
        }</code></code></p></blockquote>
<p>В функции выполняется проверка на все возможные смежные одинаковые участки. Разберем работу функции на примере последовательности 120120. Для выполнения всех проверок достаточно всего 3 прохода, при первом проходе сравниваются последние цифры 1201<strong>2</strong><strong>0</strong>, если они равны, то одинаковый участок найден и выполняется завершение работы функции, в противном случае выполняется 2-й проход и уже сравниваются цифры 01 и 20. При следующем и последнем проходе сравниваются первые и последние 3 цифры 120 и 120, вот теперь они равны и производится выход из функции, возвращается значение “false”.<span id="more-301"></span><br />
Теперь рассмотрим код процедуры “generate_Click”, которая вызывается при нажатии на кнопку “generate”.</p>
<blockquote><p><code>private void generate_Click(object sender, EventArgs e)<br />
        {<br />
            int kol = Convert.ToInt32(kolvo.Text);<br />
            Random r = new Random();<br />
            generate_num.Clear();<br />
            int x;<br />
            string s = "";<br />
            for (int i = 1; i < = kol; i++)<br />
            {<br />
                for (; ; )<br />
                {<br />
                    x = r.Next(0, 3);<br />
                    if (i == 1)<br />
                    {<br />
                        s = Convert.ToString(x);</p>
<p>                        break;<br />
                    }<br />
                    if (check_str(s + Convert.ToString(x)))<br />
                    {<br />
                        s += Convert.ToString(x);<br />
                        break;<br />
                    }<br />
                    else<br />
                    {<br />
                        if (!check_str(s + "0") &#038;&#038; !check_str(s + "1") &#038;&#038; !check_str(s + "2"))<br />
                        {<br />
                            generate_num.Text = s + " (Дальнейшая генерация числа невозможна)";<br />
                            return;<br />
                        }<br />
                    }<br />
                }<br />
            }<br />
            generate_num.Text += s;<br />
        }</code></code></p></blockquote>
<p>В этом процедуре происходит автоматическая генерация цифр от 0 до 2, добавление цифры к строке “s” (в случае положительного результата от функции “check_str”) и вывод сгенерированной последовательности на форму пользователя.<br />
Бывают такие случаи, когда невозможна дальнейшая генерации последовательности, в этом случае выводится последовательность и текст “(Дальнейшая генерация числа невозможна)”.</p>
<blockquote><p><strong>Автор</strong>: <em>Евтеев Евгений Александрович</em><br />
<strong>Email</strong>: <em>evteev_e2003@mail.ru</em></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://statprog.ru/2009/05/18/poluchit-posledovatelnost-a1%e2%80%a6an-cifr-012-v-kotoroj-net-smezhnyx-odinakovyx-uchastkov/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>В данном тексте найти наиболее часто встречающуюся последовательность символов максимальной длины</title>
		<link>http://statprog.ru/2009/05/12/posledovatelnost_max_dlin/</link>
		<comments>http://statprog.ru/2009/05/12/posledovatelnost_max_dlin/#comments</comments>
		<pubDate>Tue, 12 May 2009 12:23:45 +0000</pubDate>
		<dc:creator>evteev</dc:creator>
				<category><![CDATA[C/C++/C#]]></category>

		<guid isPermaLink="false">http://statprog.ru/?p=296</guid>
		<description><![CDATA[Для написания программы, которая будет искать в тексте последовательность символов максимальной длины, встречающуюся чаще всех остальных последовательностей, необходимо составить историю действий. Программа будет делить строку на равные части, сначала на 2, потом на 3 и так до длины строки, и &#8230; <a href="http://statprog.ru/2009/05/12/posledovatelnost_max_dlin/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Для написания программы, которая будет искать в тексте последовательность символов максимальной длины, встречающуюся чаще всех остальных последовательностей, необходимо составить историю действий. Программа будет делить строку на равные части, сначала на 2, потом на 3 и так до длины строки, и сравнивать первую часть последовательности со второй.</p>
<p>Например, строку “aabb” при делении на 2 получаем две последовательности: “aa” и “bb”, затем “aa” сравниваем с “bb”. Если первая последовательность равна второй, то указываем, что последовательность “aa” встречается в тексте 2 раза, иначе 1 раз. В данном случае “aa” встречается 1 раз. В конце выполняем поиск из последовательностей символов, которые встречаются наиболее часто, и выбираем последовательность максимальной длины.<br />
Запоминать последовательности и количество вхождений этих последовательностей будем в структуре, создадим ее:</p>
<blockquote><p><code>        public struct Symbols<br />
        {<br />
            string words;<br />
            int kolvo;</p>
<p>            public Symbols(string w, int k)<br />
            {<br />
                words = w;<br />
                kolvo = k;<br />
            }<br />
            public string Words<br />
            {<br />
                get { return words; }<br />
                set { words = value; }<br />
            }<br />
            public int Kolvo<br />
            {<br />
                get { return kolvo; }<br />
                set { kolvo = value; }<br />
            }<br />
        };</code></p></blockquote>
<p>Чтобы не добавлять в структуру одинаковые последовательности, напишем функцию, которая будет возвращать логическую “ложь” в том случае, если последовательность уже имеется в структуре:<span id="more-296"></span></p>
<blockquote><p><code>        Boolean Not_Eq_str(string c, Symbols[] sym, int k)<br />
        {<br />
            for (int i = 0; i < k; i++)<br />
                if (sym[i].Words == c)<br />
                    return false;<br />
            return true;<br />
        }</code></code></p></blockquote>
<p>Еще одна важная функция, которая будет искать в уже сформированной структуре из последовательностей и их вхождению в текст ту последовательность, которая чаще встречается и длиннее всех остальных последовательностей. Функция выводит каждую последовательность в текстовое поле “richTextBox1” и возвращает индекс найденной последовательности.</p>
<blockquote><p><code>        int search(Symbols[] sym, int k)<br />
        {<br />
            int max = 0, max_len = 0, index = 0;<br />
            for (int i = k - 1; i >= 0; i--)<br />
            {<br />
                richTextBox1.Text += sym[i].Words + " - " + sym[i].Kolvo + "\n";<br />
                if (max < sym[i].Kolvo &#038;&#038; max_len <= sym[i].Words.Length)<br />
                {<br />
                    max = sym[i].Kolvo;<br />
                    max_len = sym[i].Words.Length;<br />
                    index = i;<br />
                }<br />
            }<br />
            return index;<br />
        }</code></code></p></blockquote>
<p>И, наконец, процедура обработки события нажатия на кнопку “button1”:</p>
<blockquote><p><code>        private void button1_Click(object sender, EventArgs e)<br />
        {</code></p></blockquote>
<p>Открываем диалог для открытия текстового файла, очищаем поле “richTextBox1”, в строку “stroka” записываем текст из выбранного файла, получаем его длину и инициализируем структуру:</p>
<blockquote><p><code>            openFileDialog1.ShowDialog();<br />
            string p = openFileDialog1.FileName;<br />
            StreamReader inStream = new StreamReader(p);<br />
            patch.Text = p;<br />
            richTextBox1.Clear();<br />
            string s = "";<br />
            string stroka = "";</p>
<p>            while ((s = inStream.ReadLine()) != null)<br />
            {<br />
                stroka += s;<br />
            }<br />
            int i, l = stroka.Length, n = 0;</p>
<p>            Symbols[] sym = new Symbols[l];<br />
            int j, k = 0, x;<br />
            string subs = "";</code></p></blockquote>
<p>Если текст состоит из одного символа, выводим этот символ, указываем, что он встречается в тексте один раз и прекращаем дальнейшее выполнение кода программы:</p>
<blockquote><p><code>            if (l == 1)<br />
            {<br />
                symbols.Text = stroka;<br />
                kolvosym.Text = "1";<br />
                return;<br />
            }</code></p></blockquote>
<p>Добавляем в структуру весь текст и количество вхождений указываем равным 1:</p>
<blockquote><p><code>            sym[k].Words = stroka;<br />
            sym[k].Kolvo = 1;<br />
            k++;</code></p></blockquote>
<p>Выполняем поиск других последовательностей, исключая возможность добавления в структуру одинаковых последовательностей:</p>
<blockquote><p><code>            for (i = 2; i < l; i++)<br />
            {<br />
                if (l % i == 0)<br />
                {<br />
                    int c = l / i;<br />
                    for (j = 0; j < i; j++)<br />
                    {<br />
                        subs = stroka.Substring(j * c, c);<br />
                        x = 0;<br />
                        for (int a = 0; a < i; a++)<br />
                        {<br />
                            if (stroka.Substring(a * c, c) == subs)<br />
                                x++;<br />
                        }<br />
                        if (Not_Eq_str(subs, sym, k))<br />
                        {</p>
<p>                            sym[k].Words = subs;<br />
                            sym[k].Kolvo = x;<br />
                            k++;<br />
                        }<br />
                    }<br />
                }<br />
            }<br />
            n = k;</code></code></p></blockquote>
<p>Получаем индекс в структуре, где находится наиболее часто встречающуюся последовательность символов максимальной длины, выводим ее и количество вхождений ее в текст в поля на форму приложения:</p>
<blockquote><p><code>            int ind = search(sym, k);<br />
            symbols.Text = sym[ind].Words;<br />
            kolvosym.Text = Convert.ToString(sym[ind].Kolvo);<br />
        }</code></p></blockquote>
<p>Это конечно не самый хороший алгоритм, который дает быстрое выполнение программы, но главное же, что он работает.</p>
<blockquote><p><strong>Автор</strong>: <em>Евтеев Евгений Александрович</em><br />
<strong>Email</strong>: <em>evteev_e2003@mail.ru</em></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://statprog.ru/2009/05/12/posledovatelnost_max_dlin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Поиск чисел Пифагора в заданном диапазоне</title>
		<link>http://statprog.ru/2009/04/23/poisk-chisel-pifagora-v-zadannom-diapazone/</link>
		<comments>http://statprog.ru/2009/04/23/poisk-chisel-pifagora-v-zadannom-diapazone/#comments</comments>
		<pubDate>Thu, 23 Apr 2009 18:14:42 +0000</pubDate>
		<dc:creator>evteev</dc:creator>
				<category><![CDATA[C/C++/C#]]></category>

		<guid isPermaLink="false">http://statprog.ru/?p=257</guid>
		<description><![CDATA[Статья посвящена числам Пифагора, научимся находить их, используя программу на C#, которую мы сейчас напишем. Сначала мы должны знать, что такое число Пифагора? Число Пифагора – это число в квадрате, которое равно сумме квадратов других двух чисел. Начнем реализацию программы &#8230; <a href="http://statprog.ru/2009/04/23/poisk-chisel-pifagora-v-zadannom-diapazone/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Статья посвящена числам Пифагора, научимся находить их, используя программу на C#, которую мы сейчас напишем. Сначала мы должны знать, что такое число Пифагора? Число Пифагора – это число в квадрате, которое равно сумме квадратов других двух чисел.</p>
<p>Начнем реализацию программы с создания формы.<br />
<img src="http://statprog.ru/wp-content/cisla_piphagora-300x183.gif" alt="cisla_piphagora" title="cisla_piphagora" width="300" height="183" class="aligncenter size-medium wp-image-258" /><br />
Сразу можно создать событие выхода из программы, для этого два раза кликните по кнопке “Выход” и пропишите в процедуру следующий:</p>
<blockquote><p><code>this.Dispose(); //Принудительно завершаем работу программы </code></p></blockquote>
<p>Таким же образом создайте событие клика по кнопке “Найти”. Начинаем писать программный код для поиска чисел Пифагора.<br />
Очистим поле результатов поиска и объявим нужные переменные.</p>
<blockquote><p><code>lstFinds.Items.Clear(); //очищаем результаты поиска<br />
int i1, i2, i3, a, b; //первое, второе и третье числа, диапазон поиска</code></p></blockquote>
<p>Выполним проверку на заполнение полей диапазона.</p>
<blockquote><p><code>if (txtDiapFirst.Text != "" &#038;&#038; txtDiapSecond.Text != "") //если диапазон указан</code></p></blockquote>
<p><span id="more-257"></span></p>
<p>Используя формулы для поиска всех трех чисел, находим числа Пифагора в заданном диапазоне от “a” до “b” и выводим рельтать на форму.</p>
<blockquote><p><code>            {<br />
                a = Convert.ToInt32(txtDiapFirst.Text); //диапазон от<br />
                b = Convert.ToInt32(txtDiapSecond.Text); //до<br />
                for (int i = a; i < = b; i++)<br />
                {<br />
                    for (int j = i + 1; j <= b; j++)<br />
                    {// применяем формулы для поиска чисел<br />
                        i1 = j * j - i * i;<br />
                        i2 = 2 * i * j;<br />
                        i3 = j * j + i * i;<br />
                        if (i1 >= a &#038;&#038; i3 < = b) lstFinds.Items.Add(i1 + "^2 + " + i2 + "^2 = " + i3 + "^2");// Выводим результат поиска<br />
                    }<br />
                }<br />
            }<br />
            else MessageBox.Show("Введите значения диапазона!", "Ошибка"); //Выдаем ошибку, если одно или все поля диапазона не заполнены</code></code></p></blockquote>
<p>Если проверка не выполнилась, то выводим сообщение об ошибке без выхода из приложения для последующего исправления ошибки и поиска чисел Пифагора.<br />
<div id="attachment_259" class="wp-caption aligncenter" style="width: 310px"><img src="http://statprog.ru/wp-content/cisla_piphagora_res-300x180.gif" alt="Результат выполнения программы" title="cisla_piphagora_res" width="300" height="180" class="size-medium wp-image-259" /><p class="wp-caption-text">Результат выполнения программы</p></div><br />
Приложение написано и реализовано на языке C#, теперь оно с легкостью ищет Пифагорова числа.</p>
<blockquote><p><strong>Автор</strong>: <em>Евтеев Евгений Александрович</em><br />
<strong>Email</strong>: <em>evteev_e2003@mail.ru</em></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://statprog.ru/2009/04/23/poisk-chisel-pifagora-v-zadannom-diapazone/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Работа со структурами в C++</title>
		<link>http://statprog.ru/2009/04/11/rabota-so-strukturoj-v-c/</link>
		<comments>http://statprog.ru/2009/04/11/rabota-so-strukturoj-v-c/#comments</comments>
		<pubDate>Sat, 11 Apr 2009 15:31:41 +0000</pubDate>
		<dc:creator>evteev</dc:creator>
				<category><![CDATA[C/C++/C#]]></category>

		<guid isPermaLink="false">http://statprog.ru/?p=227</guid>
		<description><![CDATA[В этой статье вы узнаете, что такое структура и как с ней работать на C++. И так, начнем с определения структуры. Структура – это тип данных, который состоит из одного или множества других типов. Чтобы обратиться к этим типам, присвоить &#8230; <a href="http://statprog.ru/2009/04/11/rabota-so-strukturoj-v-c/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>В этой статье вы узнаете, что такое структура и как с ней работать на C++. И так, начнем с определения структуры.<br />
<strong>Структура</strong> – это тип данных, который состоит из одного или множества других типов. Чтобы обратиться к этим типам, присвоить или взять значение, нужно иметь доступ к структуре. </p>
<p>Сначала инициализируем структуру, делаем все границ всех процедур и функций:</p>
<blockquote><p><code>struct STRUCTURA<br />
{<br />
   char* PEREM1;<br />
   int PEREM2;<br />
};</code></p></blockquote>
<p>Здесь мы инициализировали структуру с именем “STRUCTURA” и двумя переменами (символьного типа и числового). Для работы со структурой нужно создать ее с заданием длины структуры и переменной, которая будет работать с ней:</p>
<blockquote><p><code>STRUCTURA str[5];</code></p></blockquote>
<p>Для ввода данных в структуру необходимо обращаться к нужному элементу структуры. Для этого создадим процедуру, в которой будет происходить заполнения структуры:</p>
<blockquote><p><code>void input(STRUCTURA * str)<br />
{<br />
  for (int i = 0; i < 5; i++)<br />
   {<br />
     	cout << i+1 << "элемент структуры - PEREM1";<br />
     	cin >> str[i]. PEREM1;<br />
     	cout < < i+1 << "элемент структуры – PEREM2";<br />
     	cin >> str[i]. PEREM2;<br />
cout< <endl;<br />
   }<br />
}</code></code></p></blockquote>
<p><span id="more-227"></span></p>
<p>str[i]. PEREM1; &#8211; означает обращение к переменной PEREM1 в i-м элементе структуры.<br />
Чтобы вывести все значения поле структуры создадим соответствующую процедуру:</p>
<blockquote><p><code>void out(STRUCTURA * str)<br />
{<br />
 	for(int i = 0; i < 5; i++)<br />
{<br />
	   cout<< i+1 << "элемент структуры - PEREM1" << str[i]. PEREM1;<br />
	   cout<< i+1 << "элемент структуры – PEREM2" << str[i]. PEREM2;<br />
}<br />
}</code></code></p></blockquote>
<p>Вызов этих процедур осуществляется с передачей параметра str, т.е. передается переменная, которая имеет доступ к структуре.</p>
<blockquote><p><code>input(str);<br />
out(str);</code></p></blockquote>
<p>В этой статье я рассказал вам как осуществлять простейшие операции работы со структурой.</p>
<blockquote><p><strong>Автор</strong>: <em>Евтеев Евгений Александрович</em><br />
<strong>Email</strong>: <em>evteev_e2003@mail.ru</em></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://statprog.ru/2009/04/11/rabota-so-strukturoj-v-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Как найти все цифры числа 100!.</title>
		<link>http://statprog.ru/2009/04/10/kak-najti-vse-cifry-chisla-100/</link>
		<comments>http://statprog.ru/2009/04/10/kak-najti-vse-cifry-chisla-100/#comments</comments>
		<pubDate>Fri, 10 Apr 2009 16:23:51 +0000</pubDate>
		<dc:creator>evteev</dc:creator>
				<category><![CDATA[C/C++/C#]]></category>

		<guid isPermaLink="false">http://statprog.ru/?p=209</guid>
		<description><![CDATA[Как найти все цифры числа 100!? Вы никогда не задавали себе этот вопрос? Это очень интересный вопрос, ведь используя, стандартный калькулятор Windows вы получите укороченную версию этого числа. Даже написав функцию вычисления факториала просто нельзя поместить ни в одну числовую &#8230; <a href="http://statprog.ru/2009/04/10/kak-najti-vse-cifry-chisla-100/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>Как найти все цифры числа 100!? </strong></p>
<p>Вы никогда не задавали себе этот вопрос? Это очень интересный вопрос, ведь используя, стандартный калькулятор Windows вы получите укороченную версию этого числа. Даже написав функцию вычисления факториала просто нельзя поместить ни в одну числовую переменную все цифры факториала 100, т.к. оно состоит из 158 цифр. О каких цифрах идет речь и как их получить, мы поговорим в этой статей.</p>
<p>Начнем с того, нам нужно написать собственную функцию умножения, так как мы умножаем на простом листке бумаги. Она будет умножать числа вида [999] * [9], т.е. числа, которые содержать одну или несколько цифр на числа, содержащие одну цифру. </p>
<blockquote><p><code>string mnog(string s, int i)<br />
        {<br />
            string res = "";<br />
            int x = 0, d, cifra = 0;<br />
            for (int j = s.Length - 1; j >= 0; j--)<br />
            {<br />
                cifra = Convert.ToInt32(s.Substring(j, 1)) * i + x;<br />
                if (j != 0)<br />
                {<br />
                    d = cifra % 10;<br />
                    x = cifra / 10;<br />
                }<br />
                else<br />
                    d = cifra;<br />
                res = Convert.ToString(d) + res;<br />
            }<br />
            return res;<br />
        }</code></p></blockquote>
<p>Входные параметры s и i – это числа, которые необходимо перемножить, соответствует выражению s * i. Алгоритм работы данной функции заключается в следующем: </p>
<ol>
<li>Извлекаем j-ю цифру из строки s (в начале это последняя цифра), умножаем ее на i и прибавляем значение полученное в пункте №3;</li>
<li>Получаем остаток от деления вычисленного значения на число 10;</li>
<li>Получаем результат от целочисленного деления вычисленного значения на 10;</li>
<li>Добавляем вычисленное значение из пункта №2 к результату;</li>
<li>Повторяем пункты №1 &#8211; №4 пока не дойдем до первой цифры из строки s. Переходим к пункту №6;</li>
<li>Повторяем пункты №1 и №4, завершаем выполнение операции умножения.</li>
</ol>
<p><span id="more-209"></span></p>
<p>Далее необходимо написать функцию для вычисления суммы двух чисел. Она также будет складывать числа, как делаем это мы.</p>
<blockquote><p><code>        string summ(string s_str1, string s_str2)<br />
        {<br />
            string summa = "";<br />
            int d = 0, cifra = 0, x = 0, sch;</p>
<p>            for (int i = 0; i < = s_str1.Length - 1; i++)<br />
            {<br />
                if (i == s_str1.Length - 1)<br />
                {<br />
                    if (s_str1.Length == s_str2.Length)<br />
                        sch = 1;<br />
                    else<br />
                        sch = s_str2.Length - i;<br />
                    d = Convert.ToInt32(s_str1.Substring(0, 1)) + Convert.ToInt32(s_str2.Substring(0, sch)) + x;<br />
                    summa = Convert.ToString(d) + summa;<br />
                    continue;<br />
                }<br />
                d = Convert.ToInt32(s_str1.Substring(s_str1.Length - i - 1, 1)) + Convert.ToInt32(s_str2.Substring(s_str2.Length - i - 1, 1)) + x;<br />
                cifra = d % 10;<br />
                x = d / 10;<br />
                summa = Convert.ToString(cifra) + summa;<br />
            }<br />
            return summa;<br />
        }</code></code></p></blockquote>
<p>Входные параметры s_str1 и s_str2 – числа, которые нужно сложить. Алгоритм работы:</p>
<ol>
<li>Вычисляем сумму i-й цифры из строки s_str1 (в начале это последняя цифра) и i-й цифры из строки s_str2, и прибавляем значение из пункта №3;</li>
<li>Получаем остаток от деления значения из пункта №1 на число 10;</li>
<li>Получаем результат от целочисленного деления значения из пункта №1 на 10;</li>
<li>Добавляем вычисленное значение из пункта №2 к результату;</li>
<li>Повторяем пункты №1 &#8211; №4 пока не дойдем до 1-й цифры из строки s_str1. Переходим к пункту №6;</li>
<li>Если количество цифр первого числа и второго совпадают, выполняем пункт №1, прибавляем его к результату. В противном случае суммируем первую цифру из строки s_str1 и значение из пункта №3, и прибавляем его к результату. Завершаем работу функции вычисления суммы.</li>
</ol>
<p>Ну и наконец, мы дошли до процедуры, вызываемой событием клика на кнопку “sol”.</p>
<blockquote><p><code>        private void sol_Click(object sender, EventArgs e)<br />
        {<br />
            string s = "99", s_str1 = "", s_str2 = "", res = "";<br />
            for (int i = 98; i >= 2; i--)<br />
            {<br />
                if (i < 10)<br />
                {<br />
                    s = mnog(s, i);<br />
                    continue;<br />
                }<br />
                if (i % 10 != 0)<br />
                {<br />
                    s_str1 = mnog(s, i % 10);<br />
                    s_str2 = mnog(s, i / 10);<br />
                    res = summ(s_str1, s_str2 + "0");<br />
                }<br />
                if (i % 10 == 0)<br />
                {<br />
                    s_str2 = mnog(s, i / 10) + "0";<br />
                    res = s_str2;<br />
                }<br />
                s = res;</p>
<p>            }<br />
            chisla.Text = s + "00";<br />
        }</code></code></p></blockquote>
<p>Здесь выполняется перемножение и суммирование чисел, начинающихся с 99 до 2, число 100 нет необходимости умножать, в конце всех вычислений просто прибавим “00”.  В этой процедуре есть необходимые условия для нормальной работы функций вычисления умножения и суммы двух чисел. В поле “chisla” запишется результат выполнения программы, т.е. все цифры числа 100! как это показано рисунке:<br />
<div id="attachment_213" class="wp-caption aligncenter" style="width: 310px"><img src="http://statprog.ru/wp-content/allchifry100_res1-300x26.gif" alt="Результат выполнения всех операций" title="allchifry100_res1" width="300" height="26" class="size-medium wp-image-213" /><p class="wp-caption-text">Результат выполнения всех операций</p></div><br />
Теперь сами можете получить все цифры факториала 100 в своей программе, со всеми операциями я вас ознакомил.</p>
<blockquote><p><strong>Автор</strong>: <em>Евтеев Евгений Александрович</em><br />
<strong>Email</strong>: <em>evteev_e2003@mail.ru</em></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://statprog.ru/2009/04/10/kak-najti-vse-cifry-chisla-100/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Поиск чисел, равных сумме факториалов своих цифр</title>
		<link>http://statprog.ru/2009/04/08/poisk-chisel-ravnyx-summe-faktorialov-svoix-cifr/</link>
		<comments>http://statprog.ru/2009/04/08/poisk-chisel-ravnyx-summe-faktorialov-svoix-cifr/#comments</comments>
		<pubDate>Wed, 08 Apr 2009 19:54:50 +0000</pubDate>
		<dc:creator>evteev</dc:creator>
				<category><![CDATA[C/C++/C#]]></category>
		<category><![CDATA[Visual Studio 2008]]></category>

		<guid isPermaLink="false">http://statprog.ru/?p=171</guid>
		<description><![CDATA[В этой статье вы узнаете, как решить и написать следующую задачу на C#: Найти числа, равные сумме факториалов своих цифр. Например, 1!+4!+5! = 145 Как эта задача решается? Мы устанавливаем диапазон чисел, среди которых будем искать такие числа, которые равны &#8230; <a href="http://statprog.ru/2009/04/08/poisk-chisel-ravnyx-summe-faktorialov-svoix-cifr/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>В этой статье вы узнаете, как решить и написать следующую задачу на <a href="http://statprog.ru/category/ccc/" title="C#">C#</a>:</p>
<ul>
<li>Найти числа, равные сумме факториалов своих цифр. Например, 1!+4!+5! = 145</li>
</ul>
<p>Как эта задача решается? Мы устанавливаем диапазон чисел, среди которых будем искать такие числа, которые равны сумме факториалов своих цифр. Дальше находим факториал каждой цифры данного числа, суммируем суммы факториалов и проверяем на равенство: [сумма] = [число], где [сумма] &#8211; это, найденная сумма факториалов всех цифр данного числа, а [число] – данное число в диапазоне.<span id="more-171"></span> Так вот, если равенство выполняется, то сохраняем это выражение в массив. Теперь реализуем этот алгоритм в программный код.<br />
<img class="aligncenter size-medium wp-image-177" title="app_findnumsummfact" src="http://statprog.ru/wp-content/app_findnumsummfact-300x248.gif" alt="app_findnumsummfact" width="300" height="248" /><br />
Для начала напишем рекурсивную функцию нахождения факториала числа. Факториал находится так: все числа от 1 до числа, факториал которого нужно найти, перемножаем.</p>
<p>Готовый код этой функции:</p>
<blockquote><p><code>int fact(int f)<br />
{<br />
int fact = 1;<br />
for (int i = 1; i &lt; = f; i++)<br />
fact *= i;<br />
return fact;<br />
}</code></p></blockquote>
<p>Процедура для кнопки “Найти”:</p>
<blockquote><p><code>private void button1_Click(object sender, EventArgs e)<br />
{<br />
int q = 0;<br />
String str = "", sint = "";<br />
listBox1.Items.Clear();<br />
DateTime start = (DateTime.Now);<br />
for (int dip = Convert.ToInt32(textBox1.Text); dip &lt; = Convert.ToInt32(textBox2.Text); dip++)<br />
{<br />
q = 0;<br />
sint = Convert.ToString(dip);<br />
int[] mass = new int[sint.Length];<br />
for (int i = 0; i &lt; sint.Length; i++)<br />
{<br />
q += sint.Substring(i, 1) == "0" ? 1 : sint.Substring(i, 1) == "1" ? 1 :<br />
sint.Substring(i, 1) == "2" ? 2 : fact(Convert.ToInt32(sint.Substring(i, 1)));<br />
mass[i] = Convert.ToInt32(sint.Substring(i, 1));<br />
}<br />
if (q == dip)<br />
{<br />
str = "";<br />
for (int i = 0; i &lt; sint.Length; i++)<br />
{<br />
if (i &lt; sint.Length - 1)<br />
str = str + Convert.ToString(mass[i]) + "! + ";<br />
else<br />
str = str + Convert.ToString(mass[i]) + "! = ";<br />
}<br />
listBox1.Items.Add(str + sint);<br />
}<br />
}<br />
DateTime end = (DateTime.Now);</code></p>
<p>listBox1.Items.Add(&laquo;Время выполнения: &raquo; + Convert.ToString(end &#8211; start));<br />
}</p></blockquote>
<p>По ходу работы программы выполняется на такие цифры как 0, 1 и 2, для них мы не выполняем поиск факториала, а просто приравниваем 1, 1 и 2 соответственно. Так как 0! = 1, 1! = 1, а 2! = 2, то мы не будем тратить процессорное время на запуск функции нахождения факториала, а приравняем соответствующие значения.<br />
Код процедуры “Завершить работу”:</p>
<blockquote><p><code>private void button3_Click(object sender, EventArgs e)<br />
{<br />
Application.Exit();<br />
}</code></p></blockquote>
<p>В этой процедуры, вызываемой нажатием на кнопку “Завершить работу”, мы вызываем событие выхода из программы.<br />
<img class="aligncenter size-medium wp-image-178" title="app_findnumsummfact_res" src="http://statprog.ru/wp-content/app_findnumsummfact_res-300x245.gif" alt="app_findnumsummfact_res" width="300" height="245" /></p>
<p>На рисунке приведен результат выполнения программы. Диапазон использовался от 0 до 1 млн. В этом диапазоне, как видите, найдено всего 4 числа, которые необходимо найти по заданию.</p>
<blockquote><p><strong>Автор</strong>: <em>Евтеев Евгений Александрович</em><br />
<strong>Email</strong>: <em>evteev_e2003@mail.ru</em></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://statprog.ru/2009/04/08/poisk-chisel-ravnyx-summe-faktorialov-svoix-cifr/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Получить все числа в диапазоне от 1 до kkk…kkk (всего n цифр) в системе счисления k</title>
		<link>http://statprog.ru/2009/04/06/poluchit-vse-chisla-v-diapazone-ot-1-do-kkk%e2%80%a6kkk-vsego-n-cifr-v-sisteme-schisleniya-k/</link>
		<comments>http://statprog.ru/2009/04/06/poluchit-vse-chisla-v-diapazone-ot-1-do-kkk%e2%80%a6kkk-vsego-n-cifr-v-sisteme-schisleniya-k/#comments</comments>
		<pubDate>Mon, 06 Apr 2009 13:24:57 +0000</pubDate>
		<dc:creator>evteev</dc:creator>
				<category><![CDATA[C/C++/C#]]></category>

		<guid isPermaLink="false">http://statprog.ru/?p=151</guid>
		<description><![CDATA[В этой статье я хочу рассмотреть задачу: Получить все числа в диапазоне от 1 до kkk…kkk (всего n цифр) в системе счисления k. K и n вводятся с клавиатуры. Основное, что должны сделать &#8211; это найти общее количество чисел, которые &#8230; <a href="http://statprog.ru/2009/04/06/poluchit-vse-chisla-v-diapazone-ot-1-do-kkk%e2%80%a6kkk-vsego-n-cifr-v-sisteme-schisleniya-k/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>В этой статье я хочу рассмотреть задачу:</strong><br />
<em>Получить все числа в диапазоне от 1 до kkk…kkk (всего n цифр) в системе счисления k. K и n вводятся с клавиатуры.</em></p>
<p>Основное, что должны сделать &#8211; это найти общее количество чисел, которые нужно декодировать в систему счисления k и саму декодировку чисел. Количество чисел должно вычисляться по формуле: max = k в степени n – 1, где max &#8211; общее количество чисел. Декодировка должна  быть универсальна, т.е. переводить десятичное число в любую систему счисления.<span id="more-151"></span></p>
<p>Создайте форму как показано на рисунке:<br />
<div id="attachment_152" class="wp-caption aligncenter" style="width: 310px"><img src="http://statprog.ru/wp-content/app_alldecoder-300x165.gif" alt="Форма программы" title="app_alldecoder" width="300" height="165" class="size-medium wp-image-152" /><p class="wp-caption-text">Форма программы</p></div></p>
<p>Поле напротив надписи “Введите число” переименуйте в “num_k”, следующее в “num_n”, а объект ListBox в “list_num”. Два раза кликните по кнопке “Получить числа” для создания процедуры вызова события клика по кнопке и скопируйте следующий код:</p>
<blockquote><p> <code>           string num_res = ""; // число в k-й системе счисления<br />
            int n_k = Convert.ToInt32(num_k.Text);<br />
            int kolvo = Convert.ToInt32(num_n.Text);</p>
<p>            int doo = Convert.ToInt32(Math.Pow(Convert.ToDouble(n_k), Convert.ToDouble(kolvo))) - 1;<br />
            groupBox_num.Text = "Все числа от 1 до " + doo  + " в " + n_k + "-й системе счисления";<br />
            groupBox_num.Visible = true;<br />
            list_num.Items.Clear();</p>
<p>            for (int i = 1; i < = doo; i++)<br />
            {<br />
                int count = 1;<br />
                if ((n_k == i &#038;&#038; n_k != 2 &#038;&#038; n_k != 16) || i / n_k < 0 || n_k == 1)<br />
                {<br />
                    num_res = Convert.ToString(i);<br />
                }<br />
                else<br />
                {<br />
                    int t = 0;<br />
                    int ch = i;<br />
                    num_res = "";<br />
                    count = 1;<br />
                    for (; ; )<br />
                    {<br />
                        string ad = "";<br />
                        int delitel = ch / n_k;<br />
                        double del = ch / n_k;<br />
                        t = ch - delitel * n_k;<br />
                        if (n_k == 16)<br />
                        {<br />
                            int b = ch % n_k;<br />
                            if (b == 10)<br />
                                ad = "A";<br />
                            else if (b == 11)<br />
                                ad = "B";<br />
                            else if (b == 12)<br />
                                ad = "C";<br />
                            else if (b == 13)<br />
                                ad = "D";<br />
                            else if (b == 14)<br />
                                ad = "E";<br />
                            else if (b == 15)<br />
                                ad = "F";<br />
                            else<br />
                                ad = Convert.ToString(t);</p>
<p>                            if( i >= 10 &#038;&#038; i < = 15)<br />
                            {<br />
                                num_res += ad;<br />
                                break;<br />
                            }<br />
                        }<br />
                        else<br />
                            ad = Convert.ToString(t);</p>
<p>                        if (del <= 0)<br />
                        {<br />
                            num_res += ad;<br />
                            break;<br />
                        }<br />
                        else<br />
                            num_res += ad;<br />
                        ch = delitel;<br />
                        count++;<br />
                    }<br />
                }</p>
<p>                char[] mass = new char[count];<br />
                mass = num_res.ToCharArray();<br />
                num_res = "";<br />
                for (int j = mass.Length - 1; j >= 0; j--)<br />
                    num_res += mass[j];<br />
                list_num.Items.Add(Convert.ToString(i) + " = " + num_res);<br />
            }</code></p></blockquote>
<p>Опишем этот код.  Сначала вычисляем общее количество чисел, которые нужно декодировать в систему счисления k по формуле, приведенной выше, и приравниваем это значение переменной “doo”. Дальше идет вычисление числа “i” в системе счисления “k”.<br />
Зачем необходимо использовать условие “if ((n_k == i &#038;&#038; n_k != 2 &#038;&#038; n_k != 16) || n_k == 1)”? Затем, чтобы не вычислять число “i” в системе счисления “k”, которое равно самой системе счисления и если система счисления равна 2 и 16 или не равна 1. Мы просто выводим значение числа “i”, т.е. не нужно переводить число “i” в систему счисления, если “i” – это система счисления.</p>
<p>Если условие не выполняется, то используем универсальный декодировщик для перевода числа “i” в систему счисления “k”. Внутри него встроен декодировщик числа в шестнадцатеричную систему счисления, т.к. в этой системе счисления числа 10, 11, 12, 13, 14, 15 равны “A”, “B”, “C”, “D”, “E”, “F” соответственно.</p>
<p>На заключительном этапе необходимо полученный результат перевода числа расположить в обратном порядке (произвести инверсию), чтобы наше число в системе счисления “k” приняло нужный формат для чтения человеку. Все, выводим результат в нашу форму.</p>
<div id="attachment_156" class="wp-caption aligncenter" style="width: 310px"><img src="http://statprog.ru/wp-content/app_alldecoder_res-300x166.gif" alt="Результат выполнения" title="app_alldecoder_res" width="300" height="166" class="size-medium wp-image-156" /><p class="wp-caption-text">Результат выполнения</p></div>
<p>Задача решена и реализована на языке C#, теперь вы можете использовать для перевода группы чисел в любую систему счисления.</p>
<blockquote><p><strong>Автор</strong>: <em>Евтеев Евгений Александрович</em><br />
<strong>Email</strong>: <em>evteev_e2003@mail.ru</em></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://statprog.ru/2009/04/06/poluchit-vse-chisla-v-diapazone-ot-1-do-kkk%e2%80%a6kkk-vsego-n-cifr-v-sisteme-schisleniya-k/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Переставить числа 0, 1 и 2 в порядке возрастания, используя перестановку 2-х элементов</title>
		<link>http://statprog.ru/2009/04/05/perestavit-chisla-0-1-i-2-v-poryadke-vozrastaniya-ispolzuya-perestanovku-2-x-elementov/</link>
		<comments>http://statprog.ru/2009/04/05/perestavit-chisla-0-1-i-2-v-poryadke-vozrastaniya-ispolzuya-perestanovku-2-x-elementov/#comments</comments>
		<pubDate>Sat, 04 Apr 2009 20:13:06 +0000</pubDate>
		<dc:creator>evteev</dc:creator>
				<category><![CDATA[C/C++/C#]]></category>
		<category><![CDATA[Visual Studio 2008]]></category>

		<guid isPermaLink="false">http://statprog.ru/?p=70</guid>
		<description><![CDATA[В данной статье будет разобрано решение следующей задачи: В массиве стоят числа 0, 1 и 2. Переставить их в порядке возрастания, если единственной разрешенной операцией (помимо чтения) над массивом является перестановка двух элементов. Реализовать программный код будем на C# в &#8230; <a href="http://statprog.ru/2009/04/05/perestavit-chisla-0-1-i-2-v-poryadke-vozrastaniya-ispolzuya-perestanovku-2-x-elementov/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>В данной статье будет разобрано решение следующей задачи:<br />
В массиве стоят числа 0, 1 и 2. Переставить их в порядке возрастания, если единственной разрешенной операцией (помимо чтения) над массивом является перестановка двух элементов.</p>
<p>Реализовать программный код будем на C# в среде разработки <a href="http://statprog.ru/page/2/">Visual Studio 2008</a> как Windows приложение с формами.<br />
Начинаем, конечно, с создания проекта с формой. На форме нужно разместить следующие объекты:<span id="more-70"></span></p>
<ol>
<li>Надпись Label.</li>
<li>Текстовое поле Textbox, переименовать имя в “cout_oper”.</li>
<li>Кнопку Button, переименовать в “work”.</li>
<li>Два текстовых поля большой длины RichTextbox, переименовать в “ data_mas ” и “date_mas_ch” соответственно.</li>
</ol>
<p>Пример показан на рисунке:<br />
<div id="attachment_72" class="wp-caption aligncenter" style="width: 310px"><img src="http://statprog.ru/wp-content/appl_9_3-300x132.gif" alt="Форма приложения" title="appl_9_3" width="300" height="132" class="size-medium wp-image-72" /><p class="wp-caption-text">Форма приложения</p></div></p>
<p>Программа не большая и довольно проста. Рассмотрим процедуру “work_Click(), которая вызывается всякий раз, когда происходит событие клика по кнопке “work”:</p>
<blockquote><p><code>        private void work_Click(object sender, EventArgs e)<br />
        {<br />
            data_mas.Clear();<br />
            date_mas_ch.Clear();<br />
            Random r = new Random();<br />
            int c_m = r.Next(10, 30), count = 0;<br />
            int[] mass = new int[c_m];<br />
            for (int i = 0; i < c_m; i++)<br />
            {<br />
                mass[i] = r.Next(0, 3);<br />
                data_mas.Text = data_mas.Text + " " + mass[i];<br />
            }<br />
            for (int i = 0; i < c_m; i++)<br />
            {<br />
                int k = i, x = mass[i];<br />
                for (int j = i + 1; j < c_m; j++)<br />
                    if (mass[j] < x)<br />
                    {<br />
                        k = j;<br />
                        x = mass[j];<br />
                        count++;<br />
                    }<br />
                mass[k] = mass[i];<br />
                mass[i] = x;<br />
            }<br />
            for (int i = 0; i < c_m; i++)<br />
                date_mas_ch.Text = date_mas_ch.Text + " " + mass[i];<br />
            cout_oper.Text = Convert.ToString(count);<br />
        }</code></p></blockquote>
<p>В этой процедуре сначала происходит очистка текстовых полей большой длины, чтобы при следующем запуске процедуры поля заполнялись только новыми данными. Дальше генерируем длину массива от 10 до 30 и создаем его. В первом цикле for происходит заполнение массива числа 0, 1 или 2 также случайно и вывод его в форму.</p>
<p>Затем мы используем сортировку, переставляя два элемента, если это необходимо. Самый последний цикл for выводит отсортированный в порядке возрастания массив в поле “date_mas_ch”, а в поле “cout_oper” записывается число равное количеству операций, которых нам понадобилось выполнить, чтобы отсортировать массив.<br />
<div id="attachment_73" class="wp-caption aligncenter" style="width: 310px"><img src="http://statprog.ru/wp-content/appl_9_3-result-300x131.gif" alt="Пример выполнения" title="appl_9_3-result" width="300" height="131" class="size-medium wp-image-73" /><p class="wp-caption-text">Пример выполнения</p></div><br />
Теперь пробуйте запустить приложение. Пример выполнения программы показан выше.</p>
<blockquote><p><strong>Автор</strong>: Евтеев Евгений Александрович<br />
<strong>Email</strong>: evteev_e2003@mail.ru</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://statprog.ru/2009/04/05/perestavit-chisla-0-1-i-2-v-poryadke-vozrastaniya-ispolzuya-perestanovku-2-x-elementov/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
